Merge branch 'infra/format' into 'main'
Adding clang-format configuration file and formatting all source files Co-authored-by: Jules Pénuchot <jules@penuchot.com> Co-authored-by: Joel FALCOU <jfalcou@codereckons.com> See merge request oss/rotgen!41
This commit is contained in:
commit
6fa95fb22d
94 changed files with 6778 additions and 4722 deletions
264
.clang-format
Normal file
264
.clang-format
Normal file
|
|
@ -0,0 +1,264 @@
|
||||||
|
## -------------------------------------------------------------------------------------------------
|
||||||
|
## SPY - C++ Informations Broker
|
||||||
|
## Copyright: SPY Project Contributors
|
||||||
|
## SPDX-License-Identifier: BSL-1.0
|
||||||
|
## -------------------------------------------------------------------------------------------------
|
||||||
|
BasedOnStyle: Microsoft
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignArrayOfStructures: None
|
||||||
|
AlignConsecutiveAssignments:
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: true
|
||||||
|
AlignConsecutiveBitFields:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveDeclarations:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveMacros:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveShortCaseStatements:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCaseArrows: false
|
||||||
|
AlignCaseColons: false
|
||||||
|
AlignConsecutiveTableGenBreakingDAGArgColons:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveTableGenCondOperatorColons:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveTableGenDefinitionColons:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments:
|
||||||
|
Kind: Always
|
||||||
|
OverEmptyLines: 0
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowBreakBeforeNoexceptSpecifier: Always
|
||||||
|
AllowShortBlocksOnASingleLine: Always
|
||||||
|
AllowShortCaseExpressionOnASingleLine: true
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortCompoundRequirementOnASingleLine: true
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: Inline
|
||||||
|
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortLoopsOnASingleLine: true
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AttributeMacros:
|
||||||
|
- __capability
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: false
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: Always
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
|
AfterObjCDeclaration: true
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: true
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakAdjacentStringLiterals: true
|
||||||
|
BreakAfterAttributes: Leave
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakAfterReturnType: None
|
||||||
|
BreakArrays: false
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeConceptDeclarations: Always
|
||||||
|
BreakBeforeInlineASMColon: OnlyMultiline
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakFunctionDefinitionParameters: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakStringLiterals: true
|
||||||
|
BreakTemplateDeclarations: MultiLine
|
||||||
|
ColumnLimit: 80
|
||||||
|
CommentPragmas: ""
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerIndentWidth: 2
|
||||||
|
ContinuationIndentWidth: 2
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
EmptyLineAfterAccessModifier: Never
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: false
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: <rotgen/detail/.*>
|
||||||
|
Priority: 1
|
||||||
|
CaseSensitive: true
|
||||||
|
SortPriority: 1
|
||||||
|
- Regex: <rotgen/.*>
|
||||||
|
Priority: 2
|
||||||
|
CaseSensitive: true
|
||||||
|
SortPriority: 2
|
||||||
|
- Regex: .*
|
||||||
|
Priority: 3
|
||||||
|
CaseSensitive: true
|
||||||
|
SortPriority: 3
|
||||||
|
IncludeIsMainRegex: ""
|
||||||
|
IncludeIsMainSourceRegex: ""
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentExternBlock: AfterExternBlock
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentRequiresClause: false
|
||||||
|
IndentWidth: 2
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
InsertBraces: false
|
||||||
|
InsertNewlineAtEOF: true
|
||||||
|
InsertTrailingCommas: None
|
||||||
|
IntegerLiteralSeparator:
|
||||||
|
Binary: 0
|
||||||
|
BinaryMinDigits: 0
|
||||||
|
Decimal: 0
|
||||||
|
DecimalMinDigits: 0
|
||||||
|
Hex: 0
|
||||||
|
HexMinDigits: 0
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLines:
|
||||||
|
AtEndOfFile: false
|
||||||
|
AtStartOfBlock: true
|
||||||
|
AtStartOfFile: true
|
||||||
|
LambdaBodyIndentation: Signature
|
||||||
|
LineEnding: LF
|
||||||
|
MacroBlockBegin: ""
|
||||||
|
MacroBlockEnd: ""
|
||||||
|
MainIncludeChar: AngleBracket
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: All
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCBreakBeforeNestedBlockParam: true
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PPIndentWidth: -1
|
||||||
|
PackConstructorInitializers: BinPack
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakOpenParenthesis: 0
|
||||||
|
PenaltyBreakScopeResolution: 500
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyIndentedWhitespace: 0
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 1000
|
||||||
|
PointerAlignment: Left
|
||||||
|
QualifierAlignment: Custom
|
||||||
|
ReferenceAlignment: Pointer
|
||||||
|
ReflowComments: true
|
||||||
|
RemoveBracesLLVM: false
|
||||||
|
RemoveParentheses: ReturnStatement
|
||||||
|
RemoveSemicolon: false
|
||||||
|
RequiresClausePosition: OwnLine
|
||||||
|
RequiresExpressionIndentation: OuterScope
|
||||||
|
SeparateDefinitionBlocks: Always
|
||||||
|
ShortNamespaceLines: 1
|
||||||
|
SkipMacroDefinitionBody: false
|
||||||
|
SortIncludes: CaseSensitive
|
||||||
|
SortJavaStaticImport: Before
|
||||||
|
SortUsingDeclarations: LexicographicNumeric
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeJsonColon: false
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeParensOptions:
|
||||||
|
AfterControlStatements: true
|
||||||
|
AfterForeachMacros: true
|
||||||
|
AfterFunctionDeclarationName: false
|
||||||
|
AfterFunctionDefinitionName: false
|
||||||
|
AfterIfMacros: true
|
||||||
|
AfterOverloadedOperator: false
|
||||||
|
AfterPlacementOperator: true
|
||||||
|
AfterRequiresInClause: false
|
||||||
|
AfterRequiresInExpression: false
|
||||||
|
BeforeNonEmptyParentheses: false
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: Never
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: -1
|
||||||
|
SpacesInParens: Never
|
||||||
|
SpacesInParensOptions:
|
||||||
|
ExceptDoubleParentheses: false
|
||||||
|
InConditionalStatements: false
|
||||||
|
InCStyleCasts: false
|
||||||
|
InEmptyParentheses: false
|
||||||
|
Other: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: c++20
|
||||||
|
TabWidth: 2
|
||||||
|
TableGenBreakInsideDAGArg: DontBreak
|
||||||
|
UseTab: Never
|
||||||
|
VerilogBreakBetweenInstancePorts: true
|
||||||
|
Language: Cpp
|
||||||
|
QualifierOrder:
|
||||||
|
- inline
|
||||||
|
- static
|
||||||
|
- type
|
||||||
|
- const
|
||||||
|
|
@ -11,26 +11,34 @@
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
template<typename M>
|
template<typename M> struct svd : find_svd<typename M::value_type, M::Options>
|
||||||
struct svd : find_svd<typename M::value_type,M::Options>
|
|
||||||
{
|
{
|
||||||
using parent = find_svd<typename M::value_type, M::Options>;
|
using parent = find_svd<typename M::value_type, M::Options>;
|
||||||
|
|
||||||
using m_type = matrix<typename M::value_type, Dynamic, Dynamic, M::Options>;
|
using m_type = matrix<typename M::value_type, Dynamic, Dynamic, M::Options>;
|
||||||
using d_type = matrix<typename M::value_type, M::ColsAtCompileTime, 1>;
|
using d_type = matrix<typename M::value_type, M::ColsAtCompileTime, 1>;
|
||||||
|
|
||||||
svd(M const& m, int options = ComputeThinU | ComputeThinV) : parent(m,options) {}
|
svd(M const& m, int options = ComputeThinU | ComputeThinV)
|
||||||
|
: parent(m, options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int rank() const { return parent::rank(); }
|
int rank() const { return parent::rank(); }
|
||||||
|
|
||||||
m_type U() const { return parent::U(); }
|
m_type U() const { return parent::U(); }
|
||||||
|
|
||||||
m_type D() const { return parent::D(); }
|
m_type D() const { return parent::D(); }
|
||||||
|
|
||||||
m_type V() const { return parent::V(); }
|
m_type V() const { return parent::V(); }
|
||||||
|
|
||||||
d_type singular_values() const { return parent::singular_values(); }
|
d_type singular_values() const { return parent::singular_values(); }
|
||||||
|
|
||||||
m_type U(int r) const { return parent::U(r); }
|
m_type U(int r) const { return parent::U(r); }
|
||||||
|
|
||||||
m_type D(int r) const { return parent::D(r); }
|
m_type D(int r) const { return parent::D(r); }
|
||||||
|
|
||||||
m_type V(int r) const { return parent::V(r); }
|
m_type V(int r) const { return parent::V(r); }
|
||||||
|
|
||||||
m_type singular_values(int r) const { return parent::singular_values(r); }
|
m_type singular_values(int r) const { return parent::singular_values(r); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -55,13 +55,27 @@ namespace rotgen
|
||||||
#undef SIZE
|
#undef SIZE
|
||||||
#undef TYPE
|
#undef TYPE
|
||||||
|
|
||||||
|
|
||||||
template<typename Scalar, int Options> struct find_svd_impl;
|
template<typename Scalar, int Options> struct find_svd_impl;
|
||||||
|
|
||||||
template<> struct find_svd_impl<float , ColMajor> { using type = svd_impl32_col; };
|
template<> struct find_svd_impl<float, ColMajor>
|
||||||
template<> struct find_svd_impl<float , RowMajor> { using type = svd_impl32_row; };
|
{
|
||||||
template<> struct find_svd_impl<double, ColMajor> { using type = svd_impl64_col; };
|
using type = svd_impl32_col;
|
||||||
template<> struct find_svd_impl<double, RowMajor> { using type = svd_impl64_row; };
|
};
|
||||||
|
|
||||||
|
template<> struct find_svd_impl<float, RowMajor>
|
||||||
|
{
|
||||||
|
using type = svd_impl32_row;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_svd_impl<double, ColMajor>
|
||||||
|
{
|
||||||
|
using type = svd_impl64_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_svd_impl<double, RowMajor>
|
||||||
|
{
|
||||||
|
using type = svd_impl64_row;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Scalar, int Options>
|
template<typename Scalar, int Options>
|
||||||
using find_svd = typename find_svd_impl<Scalar, (Options & 1)>::type;
|
using find_svd = typename find_svd_impl<Scalar, (Options & 1)>::type;
|
||||||
|
|
|
||||||
|
|
@ -40,5 +40,6 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<payload>& storage() { return storage_; }
|
std::unique_ptr<payload>& storage() { return storage_; }
|
||||||
|
|
||||||
std::unique_ptr<payload> const& storage() const { return storage_; }
|
std::unique_ptr<payload> const& storage() const { return storage_; }
|
||||||
};
|
};
|
||||||
|
|
@ -12,33 +12,38 @@
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
template<typename M>
|
template<typename M> struct svd
|
||||||
struct svd
|
|
||||||
{
|
{
|
||||||
using base = Eigen::JacobiSVD<typename M::parent>;
|
using base = Eigen::JacobiSVD<typename M::parent>;
|
||||||
using u_type = typename base::MatrixUType;
|
using u_type = typename base::MatrixUType;
|
||||||
using v_type = typename base::MatrixVType;
|
using v_type = typename base::MatrixVType;
|
||||||
using d_type = typename base::SingularValuesType;
|
using d_type = typename base::SingularValuesType;
|
||||||
|
|
||||||
svd(M const& m, int options = ComputeThinU | ComputeThinV) : svd_(m.base(),options) {}
|
svd(M const& m, int options = ComputeThinU | ComputeThinV)
|
||||||
|
: svd_(m.base(), options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int rank() const { return svd_.rank(); }
|
int rank() const { return svd_.rank(); }
|
||||||
|
|
||||||
auto singular_values() const
|
auto singular_values() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return detail::as_concrete_t<d_type, matrix>{svd_.singularValues()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return detail::as_concrete_t<d_type, matrix>{svd_.singularValues()};
|
||||||
else return svd_.singularValues();
|
else return svd_.singularValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto U() const
|
auto U() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return detail::as_concrete_t<u_type, matrix>{svd_.matrixU()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return detail::as_concrete_t<u_type, matrix>{svd_.matrixU()};
|
||||||
else return svd_.matrixU();
|
else return svd_.matrixU();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto V() const
|
auto V() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return detail::as_concrete_t<v_type, matrix>{svd_.matrixV()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return detail::as_concrete_t<v_type, matrix>{svd_.matrixV()};
|
||||||
else return svd_.matrixV();
|
else return svd_.matrixV();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,30 +51,32 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
auto d = svd_.singularValues().asDiagonal();
|
auto d = svd_.singularValues().asDiagonal();
|
||||||
if constexpr (!use_expression_templates)
|
if constexpr (!use_expression_templates)
|
||||||
return detail::as_concrete_t<decltype(d.toDenseMatrix()), matrix>{d.toDenseMatrix ()};
|
return detail::as_concrete_t<decltype(d.toDenseMatrix()), matrix>{
|
||||||
else
|
d.toDenseMatrix()};
|
||||||
return d;
|
else return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto singular_values(int r) const
|
auto singular_values(int r) const
|
||||||
{
|
{
|
||||||
auto that = svd_.singularValues().head(r);
|
auto that = svd_.singularValues().head(r);
|
||||||
if constexpr(!use_expression_templates) return detail::as_concrete_t<decltype(that), matrix>{that};
|
if constexpr (!use_expression_templates)
|
||||||
|
return detail::as_concrete_t<decltype(that), matrix>{that};
|
||||||
else return svd_.singularValues();
|
else return svd_.singularValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto U(int r) const
|
auto U(int r) const
|
||||||
{
|
{
|
||||||
auto that = svd_.matrixU().leftCols(r);
|
auto that = svd_.matrixU().leftCols(r);
|
||||||
if constexpr(!use_expression_templates) return detail::as_concrete_t<decltype(that), matrix>{that};
|
if constexpr (!use_expression_templates)
|
||||||
|
return detail::as_concrete_t<decltype(that), matrix>{that};
|
||||||
else return that;
|
else return that;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto V(int r) const
|
auto V(int r) const
|
||||||
{
|
{
|
||||||
auto that = svd_.matrixV().leftCols(r);
|
auto that = svd_.matrixV().leftCols(r);
|
||||||
if constexpr(!use_expression_templates) return detail::as_concrete_t<decltype(that), matrix>{that};
|
if constexpr (!use_expression_templates)
|
||||||
|
return detail::as_concrete_t<decltype(that), matrix>{that};
|
||||||
else return that;
|
else return that;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,9 +84,9 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
auto d = svd_.singularValues().head(r).asDiagonal();
|
auto d = svd_.singularValues().head(r).asDiagonal();
|
||||||
if constexpr (!use_expression_templates)
|
if constexpr (!use_expression_templates)
|
||||||
return detail::as_concrete_t<decltype(d.toDenseMatrix()), matrix>{d.toDenseMatrix ()};
|
return detail::as_concrete_t<decltype(d.toDenseMatrix()), matrix>{
|
||||||
else
|
d.toDenseMatrix()};
|
||||||
return d;
|
else return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ namespace rotgen::concepts
|
||||||
//! @brief Check if a type is a Rotgen reference.
|
//! @brief Check if a type is a Rotgen reference.
|
||||||
//================================================================================================
|
//================================================================================================
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept reference = requires { typename std::remove_cvref_t<T>::rotgen_ref_tag; };
|
concept reference =
|
||||||
|
requires { typename std::remove_cvref_t<T>::rotgen_ref_tag; };
|
||||||
|
|
||||||
//================================================================================================
|
//================================================================================================
|
||||||
//! @brief Check if a type is a vector.
|
//! @brief Check if a type is a vector.
|
||||||
|
|
@ -25,14 +26,14 @@ namespace rotgen::concepts
|
||||||
//! @brief Check if a type is a 3D vector.
|
//! @brief Check if a type is a 3D vector.
|
||||||
//================================================================================================
|
//================================================================================================
|
||||||
template<typename T, int N>
|
template<typename T, int N>
|
||||||
concept vectorND = vector<T> && (T::RowsAtCompileTime == N || T::ColsAtCompileTime == N);
|
concept vectorND =
|
||||||
|
vector<T> && (T::RowsAtCompileTime == N || T::ColsAtCompileTime == N);
|
||||||
|
|
||||||
//================================================================================================
|
//================================================================================================
|
||||||
//! @brief Check if a type is a ROTGEN type.
|
//! @brief Check if a type is a ROTGEN type.
|
||||||
//================================================================================================
|
//================================================================================================
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept entity = requires(T const&)
|
concept entity = requires(T const&) {
|
||||||
{
|
|
||||||
typename std::remove_cvref_t<T>::rotgen_tag;
|
typename std::remove_cvref_t<T>::rotgen_tag;
|
||||||
typename std::remove_cvref_t<T>::parent;
|
typename std::remove_cvref_t<T>::parent;
|
||||||
};
|
};
|
||||||
|
|
@ -41,14 +42,17 @@ namespace rotgen::concepts
|
||||||
//! @brief Check if a type is an EIGEN type.
|
//! @brief Check if a type is an EIGEN type.
|
||||||
//================================================================================================
|
//================================================================================================
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept eigen_compatible = requires(T const& a)
|
concept eigen_compatible = requires(T const& a) {
|
||||||
{
|
|
||||||
typename std::remove_cvref_t<T>::Scalar;
|
typename std::remove_cvref_t<T>::Scalar;
|
||||||
|
|
||||||
{ std::remove_cvref_t<T>::RowsAtCompileTime } -> std::convertible_to<int>;
|
{ std::remove_cvref_t<T>::RowsAtCompileTime } -> std::convertible_to<int>;
|
||||||
{ std::remove_cvref_t<T>::ColsAtCompileTime } -> std::convertible_to<int>;
|
{ std::remove_cvref_t<T>::ColsAtCompileTime } -> std::convertible_to<int>;
|
||||||
{ std::remove_cvref_t<T>::MaxRowsAtCompileTime } -> std::convertible_to<int>;
|
{
|
||||||
{ std::remove_cvref_t<T>::MaxColsAtCompileTime } -> std::convertible_to<int>;
|
std::remove_cvref_t<T>::MaxRowsAtCompileTime
|
||||||
|
} -> std::convertible_to<int>;
|
||||||
|
{
|
||||||
|
std::remove_cvref_t<T>::MaxColsAtCompileTime
|
||||||
|
} -> std::convertible_to<int>;
|
||||||
|
|
||||||
{ a.eval() };
|
{ a.eval() };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,7 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
using Index = std::ptrdiff_t;
|
using Index = std::ptrdiff_t;
|
||||||
|
|
||||||
inline constexpr std::ptrdiff_t default_alignment = []()
|
inline constexpr std::ptrdiff_t default_alignment = []() {
|
||||||
{
|
|
||||||
constexpr auto w = spy::simd_instruction_set.width;
|
constexpr auto w = spy::simd_instruction_set.width;
|
||||||
return w == -1 ? 0 : w / 8;
|
return w == -1 ? 0 : w / 8;
|
||||||
}();
|
}();
|
||||||
|
|
@ -50,7 +49,8 @@ namespace rotgen
|
||||||
namespace rotgen::detail
|
namespace rotgen::detail
|
||||||
{
|
{
|
||||||
template<Index R, Index C>
|
template<Index R, Index C>
|
||||||
inline constexpr int force_order = AutoAlign | ((R==1 && C!=1) ? RowMajor : ColMajor);
|
inline constexpr int force_order =
|
||||||
|
AutoAlign | ((R == 1 && C != 1) ? RowMajor : ColMajor);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(ROTGEN_MAX_SIZE) && defined(ROTGEN_ENABLE_EXPRESSION_TEMPLATES)
|
#if !defined(ROTGEN_MAX_SIZE) && defined(ROTGEN_ENABLE_EXPRESSION_TEMPLATES)
|
||||||
|
|
@ -91,8 +91,7 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
inline constexpr Index max_static_size = -1;
|
inline constexpr Index max_static_size = -1;
|
||||||
|
|
||||||
template<int Rows, int Cols>
|
template<int Rows, int Cols> inline constexpr bool storage_status = false;
|
||||||
inline constexpr bool storage_status = false;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
|
|
@ -100,9 +99,7 @@ namespace rotgen
|
||||||
inline constexpr Index max_static_size = ROTGEN_MAX_SIZE;
|
inline constexpr Index max_static_size = ROTGEN_MAX_SIZE;
|
||||||
|
|
||||||
template<int Rows, int Cols, int MaxRows, int MaxCols>
|
template<int Rows, int Cols, int MaxRows, int MaxCols>
|
||||||
inline constexpr bool storage_status =
|
inline constexpr bool storage_status = []() {
|
||||||
[]()
|
|
||||||
{
|
|
||||||
// Actual static size - vector 1xN
|
// Actual static size - vector 1xN
|
||||||
if (Rows == 1 && Cols == -1) return true;
|
if (Rows == 1 && Cols == -1) return true;
|
||||||
// Actual static size - vector Nx1
|
// Actual static size - vector Nx1
|
||||||
|
|
@ -110,7 +107,8 @@ namespace rotgen
|
||||||
// Actual static size - matrix
|
// Actual static size - matrix
|
||||||
else if (Rows > 0 && Cols > 0) return (Rows * Cols) <= max_static_size;
|
else if (Rows > 0 && Cols > 0) return (Rows * Cols) <= max_static_size;
|
||||||
// Dynamic size but static Max Size
|
// Dynamic size but static Max Size
|
||||||
else if(MaxRows > 0 && MaxCols > 0) return (MaxRows*MaxCols) <= max_static_size;
|
else if (MaxRows > 0 && MaxCols > 0)
|
||||||
|
return (MaxRows * MaxCols) <= max_static_size;
|
||||||
// Everything dynamic already
|
// Everything dynamic already
|
||||||
else return false;
|
else return false;
|
||||||
}();
|
}();
|
||||||
|
|
@ -122,16 +120,17 @@ namespace rotgen
|
||||||
inline std::ostream& setup_summary(std::ostream& os)
|
inline std::ostream& setup_summary(std::ostream& os)
|
||||||
{
|
{
|
||||||
detail::dynamic_info(os);
|
detail::dynamic_info(os);
|
||||||
os << " * Default alignment: " << default_alignment << " bytes." << std::endl;
|
os << " * Default alignment: " << default_alignment << " bytes."
|
||||||
|
<< std::endl;
|
||||||
if (!is_forcing_dynamic_status)
|
if (!is_forcing_dynamic_status)
|
||||||
{
|
{
|
||||||
if constexpr (use_expression_templates)
|
if constexpr (use_expression_templates)
|
||||||
os << " * Expression templates : Enabled." << std::endl;
|
os << " * Expression templates : Enabled." << std::endl;
|
||||||
else
|
else os << " * Expression templates : Disabled." << std::endl;
|
||||||
os << " * Expression templates : Disabled." << std::endl;
|
|
||||||
|
|
||||||
if constexpr (rotgen::max_static_size)
|
if constexpr (rotgen::max_static_size)
|
||||||
os << " * Static/Dynamic mode with maximum size: " << rotgen::max_static_size << std::endl;
|
os << " * Static/Dynamic mode with maximum size: "
|
||||||
|
<< rotgen::max_static_size << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,15 @@ namespace rotgen
|
||||||
template<typename T, int Options = T::storage_order, typename Stride = stride>
|
template<typename T, int Options = T::storage_order, typename Stride = stride>
|
||||||
class ref;
|
class ref;
|
||||||
|
|
||||||
template<typename Ref, int Rows = Dynamic, int Cols = Dynamic, bool Inner = false>
|
template<typename Ref,
|
||||||
|
int Rows = Dynamic,
|
||||||
|
int Cols = Dynamic,
|
||||||
|
bool Inner = false>
|
||||||
class block : public find_block<Ref>
|
class block : public find_block<Ref>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static_assert ( concepts::entity<Ref>
|
static_assert(concepts::entity<Ref>,
|
||||||
, "[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated"
|
"[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated");
|
||||||
);
|
|
||||||
|
|
||||||
using parent = find_block<Ref>;
|
using parent = find_block<Ref>;
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
|
|
@ -35,7 +37,8 @@ namespace rotgen
|
||||||
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
||||||
using concrete_type = matrix<value_type, Rows, Cols, storage_order>;
|
using concrete_type = matrix<value_type, Rows, Cols, storage_order>;
|
||||||
using transposed_type = matrix<value_type, Cols, Rows, storage_order>;
|
using transposed_type = matrix<value_type, Cols, Rows, storage_order>;
|
||||||
using concrete_dynamic_type = matrix<value_type,Dynamic,Dynamic,storage_order>;
|
using concrete_dynamic_type =
|
||||||
|
matrix<value_type, Dynamic, Dynamic, storage_order>;
|
||||||
|
|
||||||
static constexpr int RowsAtCompileTime = Rows;
|
static constexpr int RowsAtCompileTime = Rows;
|
||||||
static constexpr int ColsAtCompileTime = Cols;
|
static constexpr int ColsAtCompileTime = Cols;
|
||||||
|
|
@ -49,7 +52,9 @@ namespace rotgen
|
||||||
static constexpr bool has_static_storage = false;
|
static constexpr bool has_static_storage = false;
|
||||||
|
|
||||||
using parent::operator=;
|
using parent::operator=;
|
||||||
block& operator=(concepts::entity auto const& other) requires(!is_immutable)
|
|
||||||
|
block& operator=(concepts::entity auto const& other)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
|
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
|
||||||
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
||||||
|
|
@ -59,117 +64,191 @@ namespace rotgen
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block(Ref const& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
block(Ref const& r,
|
||||||
|
std::size_t i0,
|
||||||
|
std::size_t j0,
|
||||||
|
std::size_t ni,
|
||||||
|
std::size_t nj)
|
||||||
requires(!requires { typename Ref::rotgen_block_tag; } && is_immutable)
|
requires(!requires { typename Ref::rotgen_block_tag; } && is_immutable)
|
||||||
: parent(r.base(), i0, j0, ni, nj)
|
: parent(r.base(), i0, j0, ni, nj)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
block(Ref const& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
block(Ref const& r,
|
||||||
|
std::size_t i0,
|
||||||
|
std::size_t j0,
|
||||||
|
std::size_t ni,
|
||||||
|
std::size_t nj)
|
||||||
requires(requires { typename Ref::rotgen_block_tag; } && is_immutable)
|
requires(requires { typename Ref::rotgen_block_tag; } && is_immutable)
|
||||||
: parent(*r.storage(), i0, j0, ni, nj)
|
: parent(*r.storage(), i0, j0, ni, nj)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
block(Ref const& r, std::size_t i0, std::size_t j0)
|
block(Ref const& r, std::size_t i0, std::size_t j0)
|
||||||
requires(!requires{typename Ref::rotgen_block_tag; } && Rows != -1 && Cols != -1 && is_immutable)
|
requires(!requires { typename Ref::rotgen_block_tag; } && Rows != -1 &&
|
||||||
|
Cols != -1 && is_immutable)
|
||||||
: parent(r.base(), i0, j0, Rows, Cols)
|
: parent(r.base(), i0, j0, Rows, Cols)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
block(Ref const& r, std::size_t i0, std::size_t j0)
|
block(Ref const& r, std::size_t i0, std::size_t j0)
|
||||||
requires(requires{typename Ref::rotgen_block_tag; } && Rows != -1 && Cols != -1 && is_immutable)
|
requires(requires { typename Ref::rotgen_block_tag; } && Rows != -1 &&
|
||||||
|
Cols != -1 && is_immutable)
|
||||||
: parent(*r.storage(), i0, j0, Rows, Cols)
|
: parent(*r.storage(), i0, j0, Rows, Cols)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
block(
|
||||||
|
Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
||||||
requires(!requires { typename Ref::rotgen_block_tag; } && !is_immutable)
|
requires(!requires { typename Ref::rotgen_block_tag; } && !is_immutable)
|
||||||
: parent(r.base(), i0, j0, ni, nj)
|
: parent(r.base(), i0, j0, ni, nj)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
block(
|
||||||
|
Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
||||||
requires(requires { typename Ref::rotgen_block_tag; } && !is_immutable)
|
requires(requires { typename Ref::rotgen_block_tag; } && !is_immutable)
|
||||||
: parent(*r.storage(), i0, j0, ni, nj)
|
: parent(*r.storage(), i0, j0, ni, nj)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
block(Ref& r, std::size_t i0, std::size_t j0)
|
block(Ref& r, std::size_t i0, std::size_t j0)
|
||||||
requires(!requires{typename Ref::rotgen_block_tag; } && Rows != -1 && Cols != -1 && !is_immutable)
|
requires(!requires { typename Ref::rotgen_block_tag; } && Rows != -1 &&
|
||||||
|
Cols != -1 && !is_immutable)
|
||||||
: parent(r.base(), i0, j0, Rows, Cols)
|
: parent(r.base(), i0, j0, Rows, Cols)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
block(Ref& r, std::size_t i0, std::size_t j0)
|
block(Ref& r, std::size_t i0, std::size_t j0)
|
||||||
requires(requires{typename Ref::rotgen_block_tag; } && Rows != -1 && Cols != -1 && !is_immutable)
|
requires(requires { typename Ref::rotgen_block_tag; } && Rows != -1 &&
|
||||||
|
Cols != -1 && !is_immutable)
|
||||||
: parent(*r.storage(), i0, j0, Rows, Cols)
|
: parent(*r.storage(), i0, j0, Rows, Cols)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
block(parent const& base) : parent(base) {}
|
block(parent const& base) : parent(base) {}
|
||||||
|
|
||||||
bool is_contiguous_linear() const
|
bool is_contiguous_linear() const
|
||||||
{
|
{
|
||||||
if (parent::innerStride() != 1) return false;
|
if (parent::innerStride() != 1) return false;
|
||||||
if constexpr(storage_order) return parent::outerStride() == parent::cols();
|
if constexpr (storage_order)
|
||||||
|
return parent::outerStride() == parent::cols();
|
||||||
else return parent::outerStride() == parent::rows();
|
else return parent::outerStride() == parent::rows();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator()(Index i, Index j) requires(!is_immutable) { return parent::operator()(i,j); }
|
value_type& operator()(Index i, Index j)
|
||||||
|
requires(!is_immutable)
|
||||||
|
{
|
||||||
|
return parent::operator()(i, j);
|
||||||
|
}
|
||||||
|
|
||||||
value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
|
value_type& operator()(Index i)
|
||||||
|
requires(!is_immutable && IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
assert(is_contiguous_linear());
|
assert(is_contiguous_linear());
|
||||||
return parent::operator()(i);
|
return parent::operator()(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator[](Index i) requires(!is_immutable && IsVectorAtCompileTime)
|
value_type& operator[](Index i)
|
||||||
|
requires(!is_immutable && IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return (*this)(i);
|
return (*this)(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type operator()(Index i, Index j) const { return parent::operator()(i,j); }
|
value_type operator()(Index i, Index j) const
|
||||||
|
{
|
||||||
|
return parent::operator()(i, j);
|
||||||
|
}
|
||||||
|
|
||||||
value_type operator()(Index i) const requires(IsVectorAtCompileTime)
|
value_type operator()(Index i) const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
assert(is_contiguous_linear());
|
assert(is_contiguous_linear());
|
||||||
return parent::operator()(i);
|
return parent::operator()(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type operator[](Index i) const requires(IsVectorAtCompileTime)
|
value_type operator[](Index i) const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return (*this)(i);
|
return (*this)(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto evaluate() const { return *this; }
|
auto evaluate() const { return *this; }
|
||||||
|
|
||||||
decltype(auto) noalias() const { return *this; }
|
decltype(auto) noalias() const { return *this; }
|
||||||
|
|
||||||
decltype(auto) noalias() { return *this; }
|
decltype(auto) noalias() { return *this; }
|
||||||
|
|
||||||
concrete_type normalized() const requires(IsVectorAtCompileTime)
|
concrete_type normalized() const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return concrete_type(base().normalized());
|
return concrete_type(base().normalized());
|
||||||
}
|
}
|
||||||
transposed_type transpose() const { return transposed_type(base().transpose());}
|
|
||||||
concrete_type conjugate() const { return concrete_type(base().conjugate());}
|
transposed_type transpose() const
|
||||||
transposed_type adjoint() const { return transposed_type(base().adjoint());}
|
{
|
||||||
|
return transposed_type(base().transpose());
|
||||||
|
}
|
||||||
|
|
||||||
|
concrete_type conjugate() const
|
||||||
|
{
|
||||||
|
return concrete_type(base().conjugate());
|
||||||
|
}
|
||||||
|
|
||||||
|
transposed_type adjoint() const
|
||||||
|
{
|
||||||
|
return transposed_type(base().adjoint());
|
||||||
|
}
|
||||||
|
|
||||||
concrete_type cwiseAbs() const { return concrete_type(base().cwiseAbs()); }
|
concrete_type cwiseAbs() const { return concrete_type(base().cwiseAbs()); }
|
||||||
concrete_type cwiseAbs2() const { return concrete_type(base().cwiseAbs2()); }
|
|
||||||
concrete_type cwiseInverse() const { return concrete_type(base().cwiseInverse()); }
|
|
||||||
concrete_type cwiseSqrt() const { return concrete_type(base().cwiseSqrt()); }
|
|
||||||
|
|
||||||
void normalize() requires(!is_immutable && IsVectorAtCompileTime)
|
concrete_type cwiseAbs2() const
|
||||||
|
{
|
||||||
|
return concrete_type(base().cwiseAbs2());
|
||||||
|
}
|
||||||
|
|
||||||
|
concrete_type cwiseInverse() const
|
||||||
|
{
|
||||||
|
return concrete_type(base().cwiseInverse());
|
||||||
|
}
|
||||||
|
|
||||||
|
concrete_type cwiseSqrt() const
|
||||||
|
{
|
||||||
|
return concrete_type(base().cwiseSqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
void normalize()
|
||||||
|
requires(!is_immutable && IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
parent::normalize();
|
parent::normalize();
|
||||||
}
|
}
|
||||||
void transposeInPlace() requires(!is_immutable) { parent::transposeInPlace(); }
|
|
||||||
void adjointInPlace() requires(!is_immutable) { parent::adjointInPlace(); }
|
void transposeInPlace()
|
||||||
|
requires(!is_immutable)
|
||||||
|
{
|
||||||
|
parent::transposeInPlace();
|
||||||
|
}
|
||||||
|
|
||||||
|
void adjointInPlace()
|
||||||
|
requires(!is_immutable)
|
||||||
|
{
|
||||||
|
parent::adjointInPlace();
|
||||||
|
}
|
||||||
|
|
||||||
friend bool operator==(block const& lhs, block const& rhs)
|
friend bool operator==(block const& lhs, block const& rhs)
|
||||||
{
|
{
|
||||||
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs);
|
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator+=(block const& rhs) requires(!is_immutable)
|
block& operator+=(block const& rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() += static_cast<parent const&>(rhs);
|
base() += static_cast<parent const&>(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator-=(block const& rhs) requires(!is_immutable)
|
block& operator-=(block const& rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() -= static_cast<parent const&>(rhs);
|
base() -= static_cast<parent const&>(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -180,25 +259,29 @@ namespace rotgen
|
||||||
return concrete_type(static_cast<parent const&>(*this).operator-());
|
return concrete_type(static_cast<parent const&>(*this).operator-());
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator*=(block const& rhs) requires(!is_immutable)
|
block& operator*=(block const& rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() *= static_cast<parent const&>(rhs);
|
base() *= static_cast<parent const&>(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator*=(value_type rhs) requires(!is_immutable)
|
block& operator*=(value_type rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() *= rhs;
|
base() *= rhs;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator/=(value_type rhs) requires(!is_immutable)
|
block& operator/=(value_type rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() /= rhs;
|
base() /= rhs;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto minCoeff() const { return parent::minCoeff(); }
|
auto minCoeff() const { return parent::minCoeff(); }
|
||||||
|
|
||||||
auto maxCoeff() const { return parent::maxCoeff(); }
|
auto maxCoeff() const { return parent::maxCoeff(); }
|
||||||
|
|
||||||
template<std::integral IndexType>
|
template<std::integral IndexType>
|
||||||
|
|
@ -229,8 +312,12 @@ namespace rotgen
|
||||||
|
|
||||||
static concrete_type Zero(int rows, int cols)
|
static concrete_type Zero(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Zero(rows, cols);
|
return parent::Zero(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,8 +329,12 @@ namespace rotgen
|
||||||
|
|
||||||
static concrete_type Ones(int rows, int cols)
|
static concrete_type Ones(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Ones(rows, cols);
|
return parent::Ones(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,8 +346,12 @@ namespace rotgen
|
||||||
|
|
||||||
static concrete_type Constant(int rows, int cols, value_type value)
|
static concrete_type Constant(int rows, int cols, value_type value)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Constant(rows, cols, static_cast<double>(value));
|
return parent::Constant(rows, cols, static_cast<double>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -268,8 +363,12 @@ namespace rotgen
|
||||||
|
|
||||||
static concrete_type Random(int rows, int cols)
|
static concrete_type Random(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Random(rows, cols);
|
return parent::Random(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -281,49 +380,58 @@ namespace rotgen
|
||||||
|
|
||||||
static concrete_type Identity(int rows, int cols)
|
static concrete_type Identity(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Identity(rows, cols);
|
return parent::Identity(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setOnes() requires(!is_immutable)
|
block& setOnes()
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::assign(parent::Ones(parent::rows(), parent::cols()));
|
parent::assign(parent::Ones(parent::rows(), parent::cols()));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setZero() requires(!is_immutable)
|
block& setZero()
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::assign(parent::Zero(parent::rows(), parent::cols()));
|
parent::assign(parent::Zero(parent::rows(), parent::cols()));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setConstant(value_type value) requires(!is_immutable)
|
block& setConstant(value_type value)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::assign(parent::Constant(parent::rows(), parent::cols(), value));
|
parent::assign(parent::Constant(parent::rows(), parent::cols(), value));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setRandom() requires(!is_immutable)
|
block& setRandom()
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::assign(parent::Random(parent::rows(), parent::cols()));
|
parent::assign(parent::Random(parent::rows(), parent::cols()));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setIdentity() requires(!is_immutable)
|
block& setIdentity()
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::assign(parent::Identity(parent::rows(), parent::cols()));
|
parent::assign(parent::Identity(parent::rows(), parent::cols()));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int P>
|
template<int P> value_type lpNorm() const
|
||||||
value_type lpNorm() const
|
|
||||||
{
|
{
|
||||||
assert(P == 1 || P == 2 || P == Infinity);
|
assert(P == 1 || P == 2 || P == Infinity);
|
||||||
return parent::lpNorm(P);
|
return parent::lpNorm(P);
|
||||||
}
|
}
|
||||||
|
|
||||||
parent& base() { return static_cast<parent&>(*this); }
|
parent& base() { return static_cast<parent&>(*this); }
|
||||||
|
|
||||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ namespace rotgen
|
||||||
class matrix_impl32_row;
|
class matrix_impl32_row;
|
||||||
class matrix_impl32_col;
|
class matrix_impl32_col;
|
||||||
|
|
||||||
|
|
||||||
#define USE_CONST
|
#define USE_CONST
|
||||||
#define CONST const
|
#define CONST const
|
||||||
#define BASENAME block_const_impl
|
#define BASENAME block_const_impl
|
||||||
|
|
@ -42,18 +41,49 @@ namespace rotgen
|
||||||
|
|
||||||
template<typename Scalar, int Options, bool isConst> struct find_block_impl;
|
template<typename Scalar, int Options, bool isConst> struct find_block_impl;
|
||||||
|
|
||||||
template<> struct find_block_impl<float , ColMajor, true> { using type = block_const_impl32_col; };
|
template<> struct find_block_impl<float, ColMajor, true>
|
||||||
template<> struct find_block_impl<float , RowMajor, true> { using type = block_const_impl32_row; };
|
{
|
||||||
template<> struct find_block_impl<double, ColMajor, true> { using type = block_const_impl64_col; };
|
using type = block_const_impl32_col;
|
||||||
template<> struct find_block_impl<double, RowMajor, true> { using type = block_const_impl64_row; };
|
};
|
||||||
template<> struct find_block_impl<float , ColMajor, false> { using type = block_impl32_col; };
|
|
||||||
template<> struct find_block_impl<float , RowMajor, false> { using type = block_impl32_row; };
|
template<> struct find_block_impl<float, RowMajor, true>
|
||||||
template<> struct find_block_impl<double, ColMajor, false> { using type = block_impl64_col; };
|
{
|
||||||
template<> struct find_block_impl<double, RowMajor, false> { using type = block_impl64_row; };
|
using type = block_const_impl32_row;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_block_impl<double, ColMajor, true>
|
||||||
|
{
|
||||||
|
using type = block_const_impl64_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_block_impl<double, RowMajor, true>
|
||||||
|
{
|
||||||
|
using type = block_const_impl64_row;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_block_impl<float, ColMajor, false>
|
||||||
|
{
|
||||||
|
using type = block_impl32_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_block_impl<float, RowMajor, false>
|
||||||
|
{
|
||||||
|
using type = block_impl32_row;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_block_impl<double, ColMajor, false>
|
||||||
|
{
|
||||||
|
using type = block_impl64_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_block_impl<double, RowMajor, false>
|
||||||
|
{
|
||||||
|
using type = block_impl64_row;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Ref>
|
template<typename Ref>
|
||||||
using find_block = typename find_block_impl < typename std::remove_const_t<Ref>::value_type
|
using find_block =
|
||||||
, Ref::storage_order
|
typename find_block_impl<typename std::remove_const_t<Ref>::value_type,
|
||||||
, std::is_const_v<Ref>
|
Ref::storage_order,
|
||||||
>::type;
|
std::is_const_v<Ref>>::type;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,10 +95,14 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
SOURCENAME mul(TYPE s) const;
|
SOURCENAME mul(TYPE s) const;
|
||||||
SOURCENAME div(TYPE s) const;
|
SOURCENAME div(TYPE s) const;
|
||||||
|
|
||||||
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&,CLASSNAME const&);
|
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&,
|
||||||
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&, format<CLASSNAME> const&);
|
CLASSNAME const&);
|
||||||
friend ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs);
|
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&,
|
||||||
friend ROTGEN_EXPORT bool operator!=(CLASSNAME const& lhs, CLASSNAME const& rhs);
|
format<CLASSNAME> const&);
|
||||||
|
friend ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs,
|
||||||
|
CLASSNAME const& rhs);
|
||||||
|
friend ROTGEN_EXPORT bool operator!=(CLASSNAME const& lhs,
|
||||||
|
CLASSNAME const& rhs);
|
||||||
|
|
||||||
#if !defined(USE_CONST)
|
#if !defined(USE_CONST)
|
||||||
TYPE* data();
|
TYPE* data();
|
||||||
|
|
@ -106,10 +110,23 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
const TYPE* data() const;
|
const TYPE* data() const;
|
||||||
|
|
||||||
static SOURCENAME Zero(Index r, Index c) { return SOURCENAME::Zero(r, c); }
|
static SOURCENAME Zero(Index r, Index c) { return SOURCENAME::Zero(r, c); }
|
||||||
|
|
||||||
static SOURCENAME Ones(Index r, Index c) { return SOURCENAME::Ones(r, c); }
|
static SOURCENAME Ones(Index r, Index c) { return SOURCENAME::Ones(r, c); }
|
||||||
static SOURCENAME Constant(Index r, Index c, TYPE v) { return SOURCENAME::Constant(r,c,v); }
|
|
||||||
static SOURCENAME Random(Index r, Index c) { return SOURCENAME::Random(r,c); }
|
static SOURCENAME Constant(Index r, Index c, TYPE v)
|
||||||
static SOURCENAME Identity(Index r, Index c) { return SOURCENAME::Identity(r,c); }
|
{
|
||||||
|
return SOURCENAME::Constant(r, c, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SOURCENAME Random(Index r, Index c)
|
||||||
|
{
|
||||||
|
return SOURCENAME::Random(r, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SOURCENAME Identity(Index r, Index c)
|
||||||
|
{
|
||||||
|
return SOURCENAME::Identity(r, c);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#if !defined(USE_CONST)
|
#if !defined(USE_CONST)
|
||||||
|
|
|
||||||
|
|
@ -21,48 +21,71 @@ namespace rotgen
|
||||||
template<typename Ref, int Rows, int Cols, bool Inner, bool IsConst>
|
template<typename Ref, int Rows, int Cols, bool Inner, bool IsConst>
|
||||||
struct compute_block_type
|
struct compute_block_type
|
||||||
{
|
{
|
||||||
using ref_t = std::conditional_t<IsConst, typename Ref::parent const, typename Ref::parent>;
|
using ref_t = std::conditional_t<IsConst,
|
||||||
|
typename Ref::parent const,
|
||||||
|
typename Ref::parent>;
|
||||||
|
|
||||||
using type = std::conditional_t < storage_status<Rows,Cols,Rows,Cols>
|
using type = std::conditional_t<
|
||||||
, Eigen::Block<ref_t, Rows, Cols, Inner>
|
storage_status<Rows, Cols, Rows, Cols>,
|
||||||
, Eigen::Block<ref_t, Eigen::Dynamic, Eigen::Dynamic, Inner>
|
Eigen::Block<ref_t, Rows, Cols, Inner>,
|
||||||
>;
|
Eigen::Block<ref_t, Eigen::Dynamic, Eigen::Dynamic, Inner>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, int O, typename S, int Rows, int Cols, bool Inner, bool IsConst>
|
template<typename T,
|
||||||
|
int O,
|
||||||
|
typename S,
|
||||||
|
int Rows,
|
||||||
|
int Cols,
|
||||||
|
bool Inner,
|
||||||
|
bool IsConst>
|
||||||
struct compute_block_type<ref<T, O, S>, Rows, Cols, Inner, IsConst>
|
struct compute_block_type<ref<T, O, S>, Rows, Cols, Inner, IsConst>
|
||||||
: compute_block_type<typename ref<T,O,S>::parent,Rows,Cols,Inner,IsConst>
|
: compute_block_type<typename ref<T, O, S>::parent,
|
||||||
|
Rows,
|
||||||
|
Cols,
|
||||||
|
Inner,
|
||||||
|
IsConst>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Ref, int Rows, int Cols, bool Inner, bool IsConst>
|
template<typename Ref, int Rows, int Cols, bool Inner, bool IsConst>
|
||||||
using block_type = typename compute_block_type<Ref,Rows,Cols,Inner,IsConst>::type;
|
using block_type =
|
||||||
|
typename compute_block_type<Ref, Rows, Cols, Inner, IsConst>::type;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename Ref
|
template<typename Ref,
|
||||||
, int Rows = Dynamic, int Cols = Dynamic
|
int Rows = Dynamic,
|
||||||
, bool Inner = false , int ForceStorageOrder = -1
|
int Cols = Dynamic,
|
||||||
>
|
bool Inner = false,
|
||||||
class block : private detail::block_type<std::remove_const_t<Ref>, Rows, Cols, Inner,std::is_const_v<Ref> >
|
int ForceStorageOrder = -1>
|
||||||
|
class block : private detail::block_type<std::remove_const_t<Ref>,
|
||||||
|
Rows,
|
||||||
|
Cols,
|
||||||
|
Inner,
|
||||||
|
std::is_const_v<Ref>>
|
||||||
{
|
{
|
||||||
static_assert ( concepts::entity<Ref>
|
static_assert(concepts::entity<Ref>,
|
||||||
, "[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated"
|
"[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated");
|
||||||
);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
using rotgen_block_tag = void;
|
using rotgen_block_tag = void;
|
||||||
using parent = detail::block_type<std::remove_const_t<Ref>, Rows, Cols, Inner,std::is_const_v<Ref>>;
|
using parent = detail::block_type<std::remove_const_t<Ref>,
|
||||||
|
Rows,
|
||||||
|
Cols,
|
||||||
|
Inner,
|
||||||
|
std::is_const_v<Ref>>;
|
||||||
using value_type = typename parent::value_type;
|
using value_type = typename parent::value_type;
|
||||||
using Index = typename parent::Index;
|
using Index = typename parent::Index;
|
||||||
|
|
||||||
static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder;
|
static constexpr int storage_order =
|
||||||
|
(ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder;
|
||||||
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
||||||
|
|
||||||
static constexpr bool IsRowMajor = parent::IsRowMajor;
|
static constexpr bool IsRowMajor = parent::IsRowMajor;
|
||||||
|
|
||||||
using concrete_type = matrix<value_type, Rows, Cols, storage_order>;
|
using concrete_type = matrix<value_type, Rows, Cols, storage_order>;
|
||||||
using concrete_dynamic_type = matrix<value_type,Dynamic,Dynamic,storage_order>;
|
using concrete_dynamic_type =
|
||||||
|
matrix<value_type, Dynamic, Dynamic, storage_order>;
|
||||||
|
|
||||||
template<typename ET>
|
template<typename ET>
|
||||||
using as_concrete_type = detail::as_concrete_t<ET, matrix>;
|
using as_concrete_type = detail::as_concrete_t<ET, matrix>;
|
||||||
|
|
@ -74,46 +97,60 @@ namespace rotgen
|
||||||
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
||||||
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
||||||
static constexpr bool is_defined_static = Rows != -1 && Cols != -1;
|
static constexpr bool is_defined_static = Rows != -1 && Cols != -1;
|
||||||
static constexpr bool has_static_storage = storage_status<Rows,Cols,Rows,Cols>;
|
static constexpr bool has_static_storage =
|
||||||
|
storage_status<Rows, Cols, Rows, Cols>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
block(const block& other) = default;
|
block(block const& other) = default;
|
||||||
block(block&& other) = default;
|
block(block&& other) = default;
|
||||||
block& operator=(const block&) = default;
|
block& operator=(block const&) = default;
|
||||||
block& operator=(block&&) = default;
|
block& operator=(block&&) = default;
|
||||||
|
|
||||||
block(Ref const& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
block(Ref const& r,
|
||||||
|
std::size_t i0,
|
||||||
|
std::size_t j0,
|
||||||
|
std::size_t ni,
|
||||||
|
std::size_t nj)
|
||||||
requires(is_immutable)
|
requires(is_immutable)
|
||||||
: parent(r.base(), i0, j0, ni, nj)
|
: parent(r.base(), i0, j0, ni, nj)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
block(Ref const& r, std::size_t i0, std::size_t j0)
|
block(Ref const& r, std::size_t i0, std::size_t j0)
|
||||||
requires(Rows != -1 && Cols != -1 && is_immutable)
|
requires(Rows != -1 && Cols != -1 && is_immutable)
|
||||||
: parent(r.base(), i0, j0, Rows, Cols)
|
: parent(r.base(), i0, j0, Rows, Cols)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
block(
|
||||||
|
Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
: parent(r.base(), i0, j0, ni, nj)
|
: parent(r.base(), i0, j0, ni, nj)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
block(Ref& r, std::size_t i0, std::size_t j0)
|
block(Ref& r, std::size_t i0, std::size_t j0)
|
||||||
requires(Rows != -1 && Cols != -1 && !is_immutable)
|
requires(Rows != -1 && Cols != -1 && !is_immutable)
|
||||||
: parent(r.base(), i0, j0, Rows, Cols)
|
: parent(r.base(), i0, j0, Rows, Cols)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename B, Index R, Index C, bool I, int FS>
|
template<typename B, Index R, Index C, bool I, int FS>
|
||||||
block(block<B, R, C, I, FS> const& other) : parent(other.base())
|
block(block<B, R, C, I, FS> const& other) : parent(other.base())
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
block(const Eigen::MatrixBase<OtherDerived>& other) : parent(other) {}
|
block(Eigen::MatrixBase<OtherDerived> const& other) : parent(other)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
block(const Eigen::EigenBase<OtherDerived>& other) : parent(other) {}
|
block(Eigen::EigenBase<OtherDerived> const& other) : parent(other)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
block(concepts::entity auto const& other) : parent(other.base())
|
block(concepts::entity auto const& other) : parent(other.base()) {}
|
||||||
{}
|
|
||||||
|
|
||||||
block& operator=(concepts::entity auto const& other)
|
block& operator=(concepts::entity auto const& other)
|
||||||
{
|
{
|
||||||
|
|
@ -122,20 +159,21 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
block& operator=(const Eigen::MatrixBase<OtherDerived>& other)
|
block& operator=(Eigen::MatrixBase<OtherDerived> const& other)
|
||||||
{
|
{
|
||||||
parent::operator=(other);
|
parent::operator=(other);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
block& operator=(const Eigen::EigenBase<OtherDerived>& other)
|
block& operator=(Eigen::EigenBase<OtherDerived> const& other)
|
||||||
{
|
{
|
||||||
parent::operator=(other);
|
parent::operator=(other);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
parent& base() { return static_cast<parent&>(*this); }
|
parent& base() { return static_cast<parent&>(*this); }
|
||||||
|
|
||||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||||
|
|
||||||
auto evaluate() const
|
auto evaluate() const
|
||||||
|
|
@ -156,223 +194,292 @@ namespace rotgen
|
||||||
else return *this;
|
else return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto normalized() const requires(IsVectorAtCompileTime)
|
auto normalized() const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
if constexpr (use_expression_templates) return base().normalized();
|
if constexpr (use_expression_templates) return base().normalized();
|
||||||
else return as_concrete_type<decltype(base().normalized())>(base().normalized());
|
else
|
||||||
|
return as_concrete_type<decltype(base().normalized())>(
|
||||||
|
base().normalized());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto transpose() const
|
auto transpose() const
|
||||||
{
|
{
|
||||||
if constexpr (use_expression_templates) return base().transpose();
|
if constexpr (use_expression_templates) return base().transpose();
|
||||||
else return as_concrete_type<decltype(base().transpose())>(base().transpose());
|
else
|
||||||
|
return as_concrete_type<decltype(base().transpose())>(
|
||||||
|
base().transpose());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto adjoint() const
|
auto adjoint() const
|
||||||
{
|
{
|
||||||
if constexpr (use_expression_templates) return base().adjoint();
|
if constexpr (use_expression_templates) return base().adjoint();
|
||||||
else return as_concrete_type<decltype(base().adjoint())>(base().adjoint());
|
else
|
||||||
|
return as_concrete_type<decltype(base().adjoint())>(base().adjoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto conjugate() const
|
auto conjugate() const
|
||||||
{
|
{
|
||||||
if constexpr (use_expression_templates) return base().conjugate();
|
if constexpr (use_expression_templates) return base().conjugate();
|
||||||
else return as_concrete_type<decltype(base().conjugate())>(base().conjugate());
|
else
|
||||||
|
return as_concrete_type<decltype(base().conjugate())>(
|
||||||
|
base().conjugate());
|
||||||
}
|
}
|
||||||
|
|
||||||
void normalize() requires(!is_immutable && IsVectorAtCompileTime)
|
void normalize()
|
||||||
|
requires(!is_immutable && IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
parent::normalize();
|
parent::normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void transposeInPlace() requires(!is_immutable) { parent::transposeInPlace(); }
|
void transposeInPlace()
|
||||||
void adjointInPlace() requires(!is_immutable) { parent::adjointInPlace(); }
|
requires(!is_immutable)
|
||||||
|
{
|
||||||
|
parent::transposeInPlace();
|
||||||
|
}
|
||||||
|
|
||||||
|
void adjointInPlace()
|
||||||
|
requires(!is_immutable)
|
||||||
|
{
|
||||||
|
parent::adjointInPlace();
|
||||||
|
}
|
||||||
|
|
||||||
auto cwiseAbs() const
|
auto cwiseAbs() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseAbs()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseAbs()};
|
||||||
else return base().cwiseAbs();
|
else return base().cwiseAbs();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseAbs2() const
|
auto cwiseAbs2() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseAbs2()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseAbs2()};
|
||||||
else return base().cwiseAbs2();
|
else return base().cwiseAbs2();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseInverse() const
|
auto cwiseInverse() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseInverse()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseInverse()};
|
||||||
else return base().cwiseInverse();
|
else return base().cwiseInverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseSqrt() const
|
auto cwiseSqrt() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseSqrt()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseSqrt()};
|
||||||
else return base().cwiseSqrt();
|
else return base().cwiseSqrt();
|
||||||
}
|
}
|
||||||
|
|
||||||
static concrete_type Constant(value_type value) requires (Rows != -1 && Cols != -1)
|
static concrete_type Constant(value_type value)
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Constant(Rows, Cols, static_cast<value_type>(value));
|
return parent::Constant(Rows, Cols, static_cast<value_type>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static concrete_type Constant(int rows, int cols, value_type value)
|
static concrete_type Constant(int rows, int cols, value_type value)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Constant(rows, cols, static_cast<value_type>(value));
|
return parent::Constant(rows, cols, static_cast<value_type>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static concrete_type Identity() requires (Rows != -1 && Cols != -1)
|
static concrete_type Identity()
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Identity(Rows, Cols);
|
return parent::Identity(Rows, Cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static concrete_type Identity(int rows, int cols)
|
static concrete_type Identity(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Identity(rows, cols);
|
return parent::Identity(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static concrete_type Zero() requires (Rows != -1 && Cols != -1)
|
static concrete_type Zero()
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Zero(Rows, Cols);
|
return parent::Zero(Rows, Cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static concrete_type Zero(int rows, int cols)
|
static concrete_type Zero(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Zero(rows, cols);
|
return parent::Zero(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static concrete_type Ones() requires (Rows != -1 && Cols != -1)
|
static concrete_type Ones()
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Ones(Rows, Cols);
|
return parent::Ones(Rows, Cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static concrete_type Ones(int rows, int cols)
|
static concrete_type Ones(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Ones(rows, cols);
|
return parent::Ones(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static concrete_type Random() requires (Rows != -1 && Cols != -1)
|
static concrete_type Random()
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Random(Rows, Cols);
|
return parent::Random(Rows, Cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static concrete_type Random(int rows, int cols)
|
static concrete_type Random(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Random(rows, cols);
|
return parent::Random(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setOnes() requires(!is_immutable)
|
block& setOnes()
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Ones(rows(), cols());
|
*this = parent::Ones(rows(), cols());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setOnes(int r, int c) requires(!is_immutable)
|
block& setOnes(int r, int c)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Ones(r, c);
|
*this = parent::Ones(r, c);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setZero() requires(!is_immutable)
|
block& setZero()
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Zero(rows(), cols());
|
*this = parent::Zero(rows(), cols());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setZero(int r, int c) requires(!is_immutable)
|
block& setZero(int r, int c)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Zero(r, c);
|
*this = parent::Zero(r, c);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setConstant(value_type value) requires(!is_immutable)
|
block& setConstant(value_type value)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Constant(rows(), cols(), value);
|
*this = parent::Constant(rows(), cols(), value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setConstant(int r, int c, value_type value) requires(!is_immutable)
|
block& setConstant(int r, int c, value_type value)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Constant(r, c, value);
|
*this = parent::Constant(r, c, value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setRandom() requires(!is_immutable)
|
block& setRandom()
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Random(rows(), cols());
|
*this = parent::Random(rows(), cols());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setRandom(int r, int c) requires(!is_immutable)
|
block& setRandom(int r, int c)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Random(r, c);
|
*this = parent::Random(r, c);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setIdentity() requires(!is_immutable)
|
block& setIdentity()
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Identity(rows(), cols());
|
*this = parent::Identity(rows(), cols());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setIdentity(int r, int c) requires(!is_immutable)
|
block& setIdentity(int r, int c)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Identity(r, c);
|
*this = parent::Identity(r, c);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int P>
|
template<int P> value_type lpNorm() const
|
||||||
value_type lpNorm() const
|
|
||||||
{
|
{
|
||||||
static_assert(P == 1 || P == 2 || P == Infinity);
|
static_assert(P == 1 || P == 2 || P == Infinity);
|
||||||
return parent::template lpNorm<P>();
|
return parent::template lpNorm<P>();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator()(Index i, Index j) requires(!is_immutable)
|
value_type& operator()(Index i, Index j)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
return base()(i, j);
|
return base()(i, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
|
value_type& operator()(Index i)
|
||||||
|
requires(!is_immutable && IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return base().data()[i];
|
return base().data()[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator[](Index i) requires(!is_immutable && IsVectorAtCompileTime)
|
value_type& operator[](Index i)
|
||||||
|
requires(!is_immutable && IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return (*this)(i);
|
return (*this)(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type operator()(Index i, Index j) const { return base()(i, j); }
|
value_type operator()(Index i, Index j) const { return base()(i, j); }
|
||||||
value_type operator()(Index i) const requires(IsVectorAtCompileTime) { return base().data()[i]; }
|
|
||||||
value_type operator[](Index i) const requires(IsVectorAtCompileTime) { return (*this)(i); }
|
|
||||||
|
|
||||||
using parent::innerStride;
|
value_type operator()(Index i) const
|
||||||
using parent::outerStride;
|
requires(IsVectorAtCompileTime)
|
||||||
using parent::rows;
|
{
|
||||||
|
return base().data()[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type operator[](Index i) const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
|
{
|
||||||
|
return (*this)(i);
|
||||||
|
}
|
||||||
|
|
||||||
using parent::cols;
|
using parent::cols;
|
||||||
using parent::size;
|
|
||||||
using parent::prod;
|
|
||||||
using parent::mean;
|
|
||||||
using parent::trace;
|
|
||||||
using parent::squaredNorm;
|
|
||||||
using parent::norm;
|
|
||||||
using parent::sum;
|
|
||||||
using parent::data;
|
using parent::data;
|
||||||
|
using parent::innerStride;
|
||||||
|
using parent::mean;
|
||||||
|
using parent::norm;
|
||||||
|
using parent::outerStride;
|
||||||
|
using parent::prod;
|
||||||
|
using parent::rows;
|
||||||
|
using parent::size;
|
||||||
|
using parent::squaredNorm;
|
||||||
|
using parent::sum;
|
||||||
|
using parent::trace;
|
||||||
|
|
||||||
auto minCoeff() const { return parent::minCoeff(); }
|
auto minCoeff() const { return parent::minCoeff(); }
|
||||||
|
|
||||||
auto maxCoeff() const { return parent::maxCoeff(); }
|
auto maxCoeff() const { return parent::maxCoeff(); }
|
||||||
|
|
||||||
template<std::integral IndexType>
|
template<std::integral IndexType>
|
||||||
|
|
@ -396,15 +503,18 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
Index startRow() const { return base().startRow(); }
|
Index startRow() const { return base().startRow(); }
|
||||||
|
|
||||||
Index startCol() const { return base().startCol(); }
|
Index startCol() const { return base().startCol(); }
|
||||||
|
|
||||||
block& operator+=(block const& rhs) requires(!is_immutable)
|
block& operator+=(block const& rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
|
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator-=(block const& rhs) requires(!is_immutable)
|
block& operator-=(block const& rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
|
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -415,19 +525,22 @@ namespace rotgen
|
||||||
return concrete_type(static_cast<parent const&>(*this).operator-());
|
return concrete_type(static_cast<parent const&>(*this).operator-());
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator*=(block const& rhs) requires(!is_immutable)
|
block& operator*=(block const& rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
|
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator*=(value_type rhs) requires(!is_immutable)
|
block& operator*=(value_type rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) *= rhs;
|
static_cast<parent&>(*this) *= rhs;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator/=(value_type rhs) requires(!is_immutable)
|
block& operator/=(value_type rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) /= rhs;
|
static_cast<parent&>(*this) /= rhs;
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,14 @@
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
template<typename Ref, int Options = Unaligned, typename Stride = rotgen::stride>
|
template<typename Ref,
|
||||||
|
int Options = Unaligned,
|
||||||
|
typename Stride = rotgen::stride>
|
||||||
class map : public find_map<Ref>
|
class map : public find_map<Ref>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static_assert(concepts::entity<Ref>,
|
||||||
static_assert ( concepts::entity<Ref>
|
"[ROTGEN][CRITICAL] - Map of non-rotgen type instanciated");
|
||||||
, "[ROTGEN][CRITICAL] - Map of non-rotgen type instanciated"
|
|
||||||
);
|
|
||||||
|
|
||||||
using parent = find_map<Ref>;
|
using parent = find_map<Ref>;
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
|
|
@ -35,7 +35,8 @@ namespace rotgen
|
||||||
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
||||||
static constexpr bool is_defined_static = false;
|
static constexpr bool is_defined_static = false;
|
||||||
|
|
||||||
using ptr_type = std::conditional_t<is_immutable, value_type const*, value_type*>;
|
using ptr_type =
|
||||||
|
std::conditional_t<is_immutable, value_type const*, value_type*>;
|
||||||
using stride_type = Stride;
|
using stride_type = Stride;
|
||||||
|
|
||||||
static constexpr int RowsAtCompileTime = Ref::RowsAtCompileTime;
|
static constexpr int RowsAtCompileTime = Ref::RowsAtCompileTime;
|
||||||
|
|
@ -43,59 +44,76 @@ namespace rotgen
|
||||||
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
|
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
|
||||||
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
||||||
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
||||||
static constexpr bool IsCompileTimeSized = RowsAtCompileTime != -1 && ColsAtCompileTime != -1;
|
static constexpr bool IsCompileTimeSized =
|
||||||
|
RowsAtCompileTime != -1 && ColsAtCompileTime != -1;
|
||||||
|
|
||||||
using transposed_type = matrix<value_type,ColsAtCompileTime,RowsAtCompileTime, storage_order>;
|
using transposed_type =
|
||||||
|
matrix<value_type, ColsAtCompileTime, RowsAtCompileTime, storage_order>;
|
||||||
|
|
||||||
map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, strides<storage_order>(s,r,c))
|
map(ptr_type ptr, Index r, Index c, stride_type s)
|
||||||
|
: parent(ptr, r, c, strides<storage_order>(s, r, c))
|
||||||
{
|
{
|
||||||
if constexpr (RowsAtCompileTime != -1)
|
if constexpr (RowsAtCompileTime != -1)
|
||||||
assert(r == RowsAtCompileTime && "Mismatched between dynamic and static row size");
|
assert(r == RowsAtCompileTime &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
|
||||||
if constexpr (ColsAtCompileTime != -1)
|
if constexpr (ColsAtCompileTime != -1)
|
||||||
assert(c == ColsAtCompileTime && "Mismatched between dynamic and static column size");
|
assert(c == ColsAtCompileTime &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
}
|
}
|
||||||
|
|
||||||
map(ptr_type ptr, Index r, Index c)
|
map(ptr_type ptr, Index r, Index c)
|
||||||
: parent( ptr, r, c
|
: parent(ptr, r, c, [&]() {
|
||||||
, [&]()
|
if constexpr (!std::same_as<Stride, stride>)
|
||||||
{
|
return strides<storage_order>(Stride{}, r, c);
|
||||||
if constexpr(!std::same_as<Stride,stride>) return strides<storage_order>(Stride{},r,c);
|
|
||||||
else return strides<storage_order>(r, c);
|
else return strides<storage_order>(r, c);
|
||||||
}()
|
}())
|
||||||
)
|
{
|
||||||
{}
|
}
|
||||||
|
|
||||||
map(ptr_type ptr, stride_type s) requires(IsCompileTimeSized)
|
map(ptr_type ptr, stride_type s)
|
||||||
: parent(ptr,RowsAtCompileTime,ColsAtCompileTime, strides<storage_order>(s))
|
requires(IsCompileTimeSized)
|
||||||
{}
|
: parent(
|
||||||
|
ptr, RowsAtCompileTime, ColsAtCompileTime, strides<storage_order>(s))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
map(ptr_type ptr, Index size) requires(RowsAtCompileTime==1 || ColsAtCompileTime==1)
|
map(ptr_type ptr, Index size)
|
||||||
: map( ptr, RowsAtCompileTime==1?1:size, ColsAtCompileTime==1?1:size)
|
requires(RowsAtCompileTime == 1 || ColsAtCompileTime == 1)
|
||||||
{}
|
: map(ptr,
|
||||||
|
RowsAtCompileTime == 1 ? 1 : size,
|
||||||
|
ColsAtCompileTime == 1 ? 1 : size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
map(ptr_type ptr) requires(IsCompileTimeSized)
|
map(ptr_type ptr)
|
||||||
|
requires(IsCompileTimeSized)
|
||||||
: map(ptr, RowsAtCompileTime, ColsAtCompileTime)
|
: map(ptr, RowsAtCompileTime, ColsAtCompileTime)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename R2, int O2, typename S2>
|
template<typename R2, int O2, typename S2>
|
||||||
map(map<R2,O2,S2> const& other) : map ( other.data(), other.rows(), other.cols()
|
map(map<R2, O2, S2> const& other)
|
||||||
, stride{other.outerStride(),other.innerStride()}
|
: map(other.data(),
|
||||||
)
|
other.rows(),
|
||||||
{}
|
other.cols(),
|
||||||
|
stride{other.outerStride(), other.innerStride()})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
map(parent const& base) : parent(base) {}
|
map(parent const& base) : parent(base) {}
|
||||||
|
|
||||||
map(map const& other) : parent(other)
|
map(map const& other) : parent(other) {}
|
||||||
{}
|
|
||||||
|
|
||||||
map& operator=(map const& other) requires(!is_immutable)
|
map& operator=(map const& other)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() = static_cast<parent const&>(other);
|
base() = static_cast<parent const&>(other);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
map& operator=(concepts::entity auto const& other) requires(!is_immutable)
|
map& operator=(concepts::entity auto const& other)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
|
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
|
||||||
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
||||||
|
|
@ -105,57 +123,120 @@ namespace rotgen
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator()(Index i, Index j) requires(!is_immutable) { return parent::operator()(i,j); }
|
value_type& operator()(Index i, Index j)
|
||||||
value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
assert( parent::innerStride() == 1
|
return parent::operator()(i, j);
|
||||||
&& parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows())
|
}
|
||||||
);
|
|
||||||
|
value_type& operator()(Index i)
|
||||||
|
requires(!is_immutable && IsVectorAtCompileTime)
|
||||||
|
{
|
||||||
|
assert(parent::innerStride() == 1 &&
|
||||||
|
parent::outerStride() ==
|
||||||
|
(storage_order == RowMajor ? parent::cols() : parent::rows()));
|
||||||
return parent::operator()(i);
|
return parent::operator()(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator[](Index i) requires(!is_immutable && IsVectorAtCompileTime)
|
value_type& operator[](Index i)
|
||||||
|
requires(!is_immutable && IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return (*this)(i);
|
return (*this)(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type operator()(Index i, Index j) const { return parent::operator()(i,j); }
|
value_type operator()(Index i, Index j) const
|
||||||
value_type operator()(Index i) const requires(IsVectorAtCompileTime)
|
|
||||||
{
|
{
|
||||||
assert( parent::innerStride() == 1
|
return parent::operator()(i, j);
|
||||||
&& parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows())
|
}
|
||||||
);
|
|
||||||
|
value_type operator()(Index i) const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
|
{
|
||||||
|
assert(parent::innerStride() == 1 &&
|
||||||
|
parent::outerStride() ==
|
||||||
|
(storage_order == RowMajor ? parent::cols() : parent::rows()));
|
||||||
return parent::operator()(i);
|
return parent::operator()(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type operator[](Index i) const requires(IsVectorAtCompileTime)
|
value_type operator[](Index i) const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return (*this)(i);
|
return (*this)(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto evaluate() const { return *this; }
|
auto evaluate() const { return *this; }
|
||||||
|
|
||||||
decltype(auto) noalias() const { return *this; }
|
decltype(auto) noalias() const { return *this; }
|
||||||
|
|
||||||
decltype(auto) noalias() { return *this; }
|
decltype(auto) noalias() { return *this; }
|
||||||
|
|
||||||
concrete_type normalized() const requires(IsVectorAtCompileTime)
|
concrete_type normalized() const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return concrete_type(base().normalized());
|
return concrete_type(base().normalized());
|
||||||
}
|
}
|
||||||
|
|
||||||
transposed_type transpose() const { return transposed_type(base().transpose()); }
|
transposed_type transpose() const
|
||||||
concrete_type conjugate() const { return concrete_type(base().conjugate()); }
|
{
|
||||||
transposed_type adjoint() const { return transposed_type(base().adjoint()); }
|
return transposed_type(base().transpose());
|
||||||
|
}
|
||||||
|
|
||||||
|
concrete_type conjugate() const
|
||||||
|
{
|
||||||
|
return concrete_type(base().conjugate());
|
||||||
|
}
|
||||||
|
|
||||||
|
transposed_type adjoint() const
|
||||||
|
{
|
||||||
|
return transposed_type(base().adjoint());
|
||||||
|
}
|
||||||
|
|
||||||
concrete_type cwiseAbs() const { return concrete_type(base().cwiseAbs()); }
|
concrete_type cwiseAbs() const { return concrete_type(base().cwiseAbs()); }
|
||||||
concrete_type cwiseAbs2() const { return concrete_type(base().cwiseAbs2()); }
|
|
||||||
concrete_type cwiseInverse() const { return concrete_type(base().cwiseInverse()); }
|
concrete_type cwiseAbs2() const
|
||||||
concrete_type cwiseSqrt() const { return concrete_type(base().cwiseSqrt()); }
|
{
|
||||||
concrete_type cwiseMin(map const& rhs) const { return concrete_type(base().cwiseMin(rhs.base())); }
|
return concrete_type(base().cwiseAbs2());
|
||||||
concrete_type cwiseMax(map const& rhs) const { return concrete_type(base().cwiseMax(rhs.base())); }
|
}
|
||||||
concrete_type cwiseQuotient(map const& rhs) const { return concrete_type(base().cwiseQuotient(rhs.base())); }
|
|
||||||
concrete_type cwiseProduct(map const& rhs) const { return concrete_type(base().cwiseProduct(rhs.base())); }
|
concrete_type cwiseInverse() const
|
||||||
concrete_type cwiseMin(value_type s) const { return concrete_type(base().cwiseMin(s)); }
|
{
|
||||||
concrete_type cwiseMax(value_type s) const { return concrete_type(base().cwiseMax(s)); }
|
return concrete_type(base().cwiseInverse());
|
||||||
|
}
|
||||||
|
|
||||||
|
concrete_type cwiseSqrt() const
|
||||||
|
{
|
||||||
|
return concrete_type(base().cwiseSqrt());
|
||||||
|
}
|
||||||
|
|
||||||
|
concrete_type cwiseMin(map const& rhs) const
|
||||||
|
{
|
||||||
|
return concrete_type(base().cwiseMin(rhs.base()));
|
||||||
|
}
|
||||||
|
|
||||||
|
concrete_type cwiseMax(map const& rhs) const
|
||||||
|
{
|
||||||
|
return concrete_type(base().cwiseMax(rhs.base()));
|
||||||
|
}
|
||||||
|
|
||||||
|
concrete_type cwiseQuotient(map const& rhs) const
|
||||||
|
{
|
||||||
|
return concrete_type(base().cwiseQuotient(rhs.base()));
|
||||||
|
}
|
||||||
|
|
||||||
|
concrete_type cwiseProduct(map const& rhs) const
|
||||||
|
{
|
||||||
|
return concrete_type(base().cwiseProduct(rhs.base()));
|
||||||
|
}
|
||||||
|
|
||||||
|
concrete_type cwiseMin(value_type s) const
|
||||||
|
{
|
||||||
|
return concrete_type(base().cwiseMin(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
concrete_type cwiseMax(value_type s) const
|
||||||
|
{
|
||||||
|
return concrete_type(base().cwiseMax(s));
|
||||||
|
}
|
||||||
|
|
||||||
concrete_type inverse() const { return concrete_type(base().inverse()); }
|
concrete_type inverse() const { return concrete_type(base().inverse()); }
|
||||||
|
|
||||||
|
|
@ -177,22 +258,35 @@ namespace rotgen
|
||||||
return that;
|
return that;
|
||||||
}
|
}
|
||||||
|
|
||||||
void normalize() requires(!is_immutable && IsVectorAtCompileTime)
|
void normalize()
|
||||||
|
requires(!is_immutable && IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
parent::normalize();
|
parent::normalize();
|
||||||
}
|
}
|
||||||
void transposeInPlace() requires(!is_immutable) { parent::transposeInPlace(); }
|
|
||||||
void adjointInPlace() requires(!is_immutable) { parent::adjointInPlace(); }
|
void transposeInPlace()
|
||||||
|
requires(!is_immutable)
|
||||||
|
{
|
||||||
|
parent::transposeInPlace();
|
||||||
|
}
|
||||||
|
|
||||||
|
void adjointInPlace()
|
||||||
|
requires(!is_immutable)
|
||||||
|
{
|
||||||
|
parent::adjointInPlace();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename R2, int O2, typename S2>
|
template<typename R2, int O2, typename S2>
|
||||||
map& operator+=(map<R2,O2,S2> const& rhs) requires(!is_immutable)
|
map& operator+=(map<R2, O2, S2> const& rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() += rhs.base();
|
base() += rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R2, int O2, typename S2>
|
template<typename R2, int O2, typename S2>
|
||||||
map& operator-=(map<R2,O2,S2> const& rhs) requires(!is_immutable)
|
map& operator-=(map<R2, O2, S2> const& rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() -= rhs.base();
|
base() -= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -204,25 +298,29 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R2, int O2, typename S2>
|
template<typename R2, int O2, typename S2>
|
||||||
map& operator*=(map<R2,O2,S2> const& rhs) requires(!is_immutable)
|
map& operator*=(map<R2, O2, S2> const& rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() *= rhs.base();
|
base() *= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
map& operator*=(value_type rhs) requires(!is_immutable)
|
map& operator*=(value_type rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() *= rhs;
|
base() *= rhs;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
map& operator/=(value_type rhs) requires(!is_immutable)
|
map& operator/=(value_type rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() /= rhs;
|
base() /= rhs;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto minCoeff() const { return parent::minCoeff(); }
|
auto minCoeff() const { return parent::minCoeff(); }
|
||||||
|
|
||||||
auto maxCoeff() const { return parent::maxCoeff(); }
|
auto maxCoeff() const { return parent::maxCoeff(); }
|
||||||
|
|
||||||
template<std::integral IndexType>
|
template<std::integral IndexType>
|
||||||
|
|
@ -245,17 +343,16 @@ namespace rotgen
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto Zero() requires( requires {Ref::Zero();} )
|
static auto Zero()
|
||||||
|
requires(requires { Ref::Zero(); })
|
||||||
{
|
{
|
||||||
return Ref::Zero();
|
return Ref::Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto Zero(int rows, int cols)
|
static auto Zero(int rows, int cols) { return Ref::Zero(rows, cols); }
|
||||||
{
|
|
||||||
return Ref::Zero(rows,cols);
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto Constant(value_type value) requires( requires {Ref::Constant(value);} )
|
static auto Constant(value_type value)
|
||||||
|
requires(requires { Ref::Constant(value); })
|
||||||
{
|
{
|
||||||
return Ref::Constant(value);
|
return Ref::Constant(value);
|
||||||
}
|
}
|
||||||
|
|
@ -265,17 +362,16 @@ namespace rotgen
|
||||||
return Ref::Constant(rows, cols, value);
|
return Ref::Constant(rows, cols, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto Random() requires( requires {Ref::Random();} )
|
static auto Random()
|
||||||
|
requires(requires { Ref::Random(); })
|
||||||
{
|
{
|
||||||
return Ref::Random();
|
return Ref::Random();
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto Random(int rows, int cols)
|
static auto Random(int rows, int cols) { return Ref::Random(rows, cols); }
|
||||||
{
|
|
||||||
return Ref::Random(rows, cols);
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto Identity() requires( requires {Ref::Identity();} )
|
static auto Identity()
|
||||||
|
requires(requires { Ref::Identity(); })
|
||||||
{
|
{
|
||||||
return Ref::Identity();
|
return Ref::Identity();
|
||||||
}
|
}
|
||||||
|
|
@ -285,31 +381,36 @@ namespace rotgen
|
||||||
return Ref::Identity(rows, cols);
|
return Ref::Identity(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
map& setZero() requires(!is_immutable)
|
map& setZero()
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::setZero();
|
parent::setZero();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
map& setOnes() requires(!is_immutable)
|
map& setOnes()
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::setOnes();
|
parent::setOnes();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
map& setIdentity() requires(!is_immutable)
|
map& setIdentity()
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::setIdentity();
|
parent::setIdentity();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
map& setRandom() requires(!is_immutable)
|
map& setRandom()
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::setRandom();
|
parent::setRandom();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
map& setConstant(value_type s) requires(!is_immutable)
|
map& setConstant(value_type s)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::setConstant(s);
|
parent::setConstant(s);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -321,14 +422,14 @@ namespace rotgen
|
||||||
return base().dot(rhs.base());
|
return base().dot(rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int P>
|
template<int P> value_type lpNorm() const
|
||||||
value_type lpNorm() const
|
|
||||||
{
|
{
|
||||||
assert(P == 1 || P == 2 || P == Infinity);
|
assert(P == 1 || P == 2 || P == Infinity);
|
||||||
return parent::lpNorm(P);
|
return parent::lpNorm(P);
|
||||||
}
|
}
|
||||||
|
|
||||||
parent& base() { return static_cast<parent&>(*this); }
|
parent& base() { return static_cast<parent&>(*this); }
|
||||||
|
|
||||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||||
|
|
||||||
concrete_type qr_solve(map const& rhs) const
|
concrete_type qr_solve(map const& rhs) const
|
||||||
|
|
@ -338,7 +439,8 @@ namespace rotgen
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
||||||
detail::composite_type<R1,R2,matrix> operator+(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
|
detail::composite_type<R1, R2, matrix> operator+(map<R1, O1, S1> const& lhs,
|
||||||
|
map<R2, O2, S2> const& rhs)
|
||||||
{
|
{
|
||||||
using map1_type = map<R1 const, O1, S1>;
|
using map1_type = map<R1 const, O1, S1>;
|
||||||
using map2_type = map<R2 const, O2, S2>;
|
using map2_type = map<R2 const, O2, S2>;
|
||||||
|
|
@ -347,7 +449,8 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
||||||
detail::composite_type<R1,R2,matrix> operator-(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
|
detail::composite_type<R1, R2, matrix> operator-(map<R1, O1, S1> const& lhs,
|
||||||
|
map<R2, O2, S2> const& rhs)
|
||||||
{
|
{
|
||||||
using map1_type = map<R1 const, O1, S1>;
|
using map1_type = map<R1 const, O1, S1>;
|
||||||
using map2_type = map<R2 const, O2, S2>;
|
using map2_type = map<R2 const, O2, S2>;
|
||||||
|
|
@ -356,38 +459,39 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
||||||
matrix<typename R1::value_type,R1::RowsAtCompileTime,R2::ColsAtCompileTime,R1::storage_order>
|
matrix<typename R1::value_type,
|
||||||
|
R1::RowsAtCompileTime,
|
||||||
|
R2::ColsAtCompileTime,
|
||||||
|
R1::storage_order>
|
||||||
operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
||||||
{
|
{
|
||||||
using map1_type = map<R1 const, O1, S1>;
|
using map1_type = map<R1 const, O1, S1>;
|
||||||
using map2_type = map<R2 const, O2, S2>;
|
using map2_type = map<R2 const, O2, S2>;
|
||||||
using concrete_type = matrix< typename R1::value_type
|
using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime,
|
||||||
, R1::RowsAtCompileTime,R2::ColsAtCompileTime
|
R2::ColsAtCompileTime, R1::storage_order>;
|
||||||
, R1::storage_order
|
|
||||||
>;
|
|
||||||
|
|
||||||
return concrete_type(map1_type(lhs).base().mul(map2_type(rhs).base()));
|
return concrete_type(map1_type(lhs).base().mul(map2_type(rhs).base()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, int O, typename S>
|
template<typename R, int O, typename S>
|
||||||
typename map<R,O,S>::concrete_type
|
typename map<R, O, S>::concrete_type operator*(
|
||||||
operator*(map<R,O,S> const& lhs, std::convertible_to<typename R::value_type> auto s)
|
map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s)
|
||||||
{
|
{
|
||||||
using concrete_type = typename map<R, O, S>::concrete_type;
|
using concrete_type = typename map<R, O, S>::concrete_type;
|
||||||
return concrete_type(lhs.base().mul(s));
|
return concrete_type(lhs.base().mul(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, int O, typename S>
|
template<typename R, int O, typename S>
|
||||||
typename map<R,O,S>::concrete_type
|
typename map<R, O, S>::concrete_type operator*(
|
||||||
operator*(std::convertible_to<typename R::value_type> auto s, map<R,O,S> const& rhs)
|
std::convertible_to<typename R::value_type> auto s, map<R, O, S> const& rhs)
|
||||||
{
|
{
|
||||||
using concrete_type = typename map<R, O, S>::concrete_type;
|
using concrete_type = typename map<R, O, S>::concrete_type;
|
||||||
return concrete_type(rhs.base().mul(s));
|
return concrete_type(rhs.base().mul(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, int O, typename S>
|
template<typename R, int O, typename S>
|
||||||
typename map<R,O,S>::concrete_type
|
typename map<R, O, S>::concrete_type operator/(
|
||||||
operator/(map<R,O,S> const& lhs, std::convertible_to<typename R::value_type> auto s)
|
map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s)
|
||||||
{
|
{
|
||||||
using concrete_type = typename map<R, O, S>::concrete_type;
|
using concrete_type = typename map<R, O, S>::concrete_type;
|
||||||
return concrete_type(lhs.base().div(s));
|
return concrete_type(lhs.base().div(s));
|
||||||
|
|
@ -398,6 +502,7 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
return lhs.base() == rhs.base();
|
return lhs.base() == rhs.base();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R1, int O1, typename S1, typename R2, int O2, typename S2>
|
template<typename R1, int O1, typename S1, typename R2, int O2, typename S2>
|
||||||
bool operator!=(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
bool operator!=(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -41,20 +41,51 @@ namespace rotgen
|
||||||
|
|
||||||
template<typename Scalar, int Options, bool isConst> struct find_map_impl;
|
template<typename Scalar, int Options, bool isConst> struct find_map_impl;
|
||||||
|
|
||||||
template<> struct find_map_impl<float , ColMajor, true> { using type = map_const_impl32_col; };
|
template<> struct find_map_impl<float, ColMajor, true>
|
||||||
template<> struct find_map_impl<float , RowMajor, true> { using type = map_const_impl32_row; };
|
{
|
||||||
template<> struct find_map_impl<double, ColMajor, true> { using type = map_const_impl64_col; };
|
using type = map_const_impl32_col;
|
||||||
template<> struct find_map_impl<double, RowMajor, true> { using type = map_const_impl64_row; };
|
};
|
||||||
template<> struct find_map_impl<float , ColMajor, false> { using type = map_impl32_col; };
|
|
||||||
template<> struct find_map_impl<float , RowMajor, false> { using type = map_impl32_row; };
|
template<> struct find_map_impl<float, RowMajor, true>
|
||||||
template<> struct find_map_impl<double, ColMajor, false> { using type = map_impl64_col; };
|
{
|
||||||
template<> struct find_map_impl<double, RowMajor, false> { using type = map_impl64_row; };
|
using type = map_const_impl32_row;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_map_impl<double, ColMajor, true>
|
||||||
|
{
|
||||||
|
using type = map_const_impl64_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_map_impl<double, RowMajor, true>
|
||||||
|
{
|
||||||
|
using type = map_const_impl64_row;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_map_impl<float, ColMajor, false>
|
||||||
|
{
|
||||||
|
using type = map_impl32_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_map_impl<float, RowMajor, false>
|
||||||
|
{
|
||||||
|
using type = map_impl32_row;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_map_impl<double, ColMajor, false>
|
||||||
|
{
|
||||||
|
using type = map_impl64_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_map_impl<double, RowMajor, false>
|
||||||
|
{
|
||||||
|
using type = map_impl64_row;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Ref>
|
template<typename Ref>
|
||||||
using find_map = typename find_map_impl < typename std::remove_const_t<Ref>::value_type
|
using find_map =
|
||||||
, Ref::storage_order
|
typename find_map_impl<typename std::remove_const_t<Ref>::value_type,
|
||||||
, std::is_const_v<Ref>
|
Ref::storage_order,
|
||||||
>::type;
|
std::is_const_v<Ref>>::type;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <rotgen/container/map/dynamic/operators.hpp>
|
#include <rotgen/container/map/dynamic/operators.hpp>
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,6 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
TYPE operator()(Index i, Index j) const;
|
TYPE operator()(Index i, Index j) const;
|
||||||
TYPE operator()(Index i) const;
|
TYPE operator()(Index i) const;
|
||||||
|
|
||||||
|
|
||||||
#if !defined(USE_CONST)
|
#if !defined(USE_CONST)
|
||||||
CLASSNAME& operator+=(CLASSNAME const& rhs);
|
CLASSNAME& operator+=(CLASSNAME const& rhs);
|
||||||
CLASSNAME& operator+=(CLASSCONSTNAME const& rhs);
|
CLASSNAME& operator+=(CLASSCONSTNAME const& rhs);
|
||||||
|
|
@ -106,8 +105,10 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
|
|
||||||
SOURCENAME inverse() const;
|
SOURCENAME inverse() const;
|
||||||
|
|
||||||
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&, CLASSNAME const&);
|
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&,
|
||||||
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&, format<CLASSNAME> const&);
|
CLASSNAME const&);
|
||||||
|
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&,
|
||||||
|
format<CLASSNAME> const&);
|
||||||
const TYPE* data() const;
|
const TYPE* data() const;
|
||||||
|
|
||||||
#if !defined(USE_CONST)
|
#if !defined(USE_CONST)
|
||||||
|
|
@ -119,8 +120,10 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
void setConstant(TYPE);
|
void setConstant(TYPE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
friend ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs);
|
friend ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs,
|
||||||
friend ROTGEN_EXPORT bool operator!=(CLASSNAME const& lhs, CLASSNAME const& rhs);
|
CLASSNAME const& rhs);
|
||||||
|
friend ROTGEN_EXPORT bool operator!=(CLASSNAME const& lhs,
|
||||||
|
CLASSNAME const& rhs);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct payload;
|
struct payload;
|
||||||
|
|
@ -128,5 +131,6 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<payload>& storage() { return storage_; }
|
std::unique_ptr<payload>& storage() { return storage_; }
|
||||||
|
|
||||||
std::unique_ptr<payload> const& storage() const { return storage_; }
|
std::unique_ptr<payload> const& storage() const { return storage_; }
|
||||||
};
|
};
|
||||||
|
|
@ -9,7 +9,10 @@
|
||||||
|
|
||||||
#define ROTGEN_DEF_RELOP_PAIR(OP, T1, T2) \
|
#define ROTGEN_DEF_RELOP_PAIR(OP, T1, T2) \
|
||||||
ROTGEN_EXPORT bool operator OP(T1 const&, T2 const&); \
|
ROTGEN_EXPORT bool operator OP(T1 const&, T2 const&); \
|
||||||
inline bool operator OP (T2 const& a, T1 const& b) { return b OP a; } \
|
inline bool operator OP(T2 const& a, T1 const& b) \
|
||||||
|
{ \
|
||||||
|
return b OP a; \
|
||||||
|
} \
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
#define ROTGEN_DEF_RELOP(OP) \
|
#define ROTGEN_DEF_RELOP(OP) \
|
||||||
|
|
@ -24,7 +27,8 @@ ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl64_col, map_impl64_row) \
|
||||||
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl64_col, map_const_impl64_row) \
|
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl64_col, map_const_impl64_row) \
|
||||||
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl64_row, map_impl64_row) \
|
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl64_row, map_impl64_row) \
|
||||||
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl64_row, map_impl64_col) \
|
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl64_row, map_impl64_col) \
|
||||||
ROTGEN_DEF_RELOP_PAIR(OP, map_impl64_col, map_impl64_row) \
|
ROTGEN_DEF_RELOP_PAIR(OP, map_impl64_col, map_impl64_row)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,12 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename Ref, int Options, bool isConst>
|
template<typename Ref, int Options, bool isConst> struct compute_map_type
|
||||||
struct compute_map_type
|
|
||||||
{
|
{
|
||||||
using base = Eigen::Matrix< typename Ref::value_type
|
using base = Eigen::Matrix<typename Ref::value_type,
|
||||||
, Ref::RowsAtCompileTime, Ref::ColsAtCompileTime
|
Ref::RowsAtCompileTime,
|
||||||
, Ref::storage_order
|
Ref::ColsAtCompileTime,
|
||||||
>;
|
Ref::storage_order>;
|
||||||
|
|
||||||
using ref_t = std::conditional_t<isConst, base const, base>;
|
using ref_t = std::conditional_t<isConst, base const, base>;
|
||||||
using type = Eigen::Map<ref_t, Options, Eigen::Stride<-1, -1>>;
|
using type = Eigen::Map<ref_t, Options, Eigen::Stride<-1, -1>>;
|
||||||
|
|
@ -31,11 +30,14 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ref, int Options = Unaligned, typename Stride = stride>
|
template<typename Ref, int Options = Unaligned, typename Stride = stride>
|
||||||
class map : private detail::map_type<std::remove_const_t<Ref>, Options, std::is_const_v<Ref>>
|
class map : private detail::map_type<std::remove_const_t<Ref>,
|
||||||
|
Options,
|
||||||
|
std::is_const_v<Ref>>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
using parent = detail::map_type<std::remove_const_t<Ref>, Options, std::is_const_v<Ref>>;
|
using parent =
|
||||||
|
detail::map_type<std::remove_const_t<Ref>, Options, std::is_const_v<Ref>>;
|
||||||
using value_type = typename std::remove_const_t<Ref>::value_type;
|
using value_type = typename std::remove_const_t<Ref>::value_type;
|
||||||
using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
|
using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
|
||||||
|
|
||||||
|
|
@ -52,39 +54,50 @@ namespace rotgen
|
||||||
template<typename ET>
|
template<typename ET>
|
||||||
using as_concrete_type = detail::as_concrete_t<ET, matrix>;
|
using as_concrete_type = detail::as_concrete_t<ET, matrix>;
|
||||||
|
|
||||||
using ptr_type = std::conditional_t<is_immutable, value_type const*, value_type*>;
|
using ptr_type =
|
||||||
|
std::conditional_t<is_immutable, value_type const*, value_type*>;
|
||||||
using stride_type = Stride;
|
using stride_type = Stride;
|
||||||
|
|
||||||
map(const map&) = default;
|
map(map const&) = default;
|
||||||
map(map&&) = default;
|
map(map&&) = default;
|
||||||
map& operator=(const map&) = default;
|
map& operator=(map const&) = default;
|
||||||
map& operator=(map&&) = default;
|
map& operator=(map&&) = default;
|
||||||
|
|
||||||
map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, strides<storage_order>(s,r,c)) {}
|
map(ptr_type ptr, Index r, Index c, stride_type s)
|
||||||
map(ptr_type ptr, Index r, Index c)
|
: parent(ptr, r, c, strides<storage_order>(s, r, c))
|
||||||
: parent( ptr, r, c
|
|
||||||
, [&]()
|
|
||||||
{
|
{
|
||||||
if constexpr(!std::same_as<Stride,stride>) return strides<storage_order>(Stride{},r,c);
|
}
|
||||||
|
|
||||||
|
map(ptr_type ptr, Index r, Index c)
|
||||||
|
: parent(ptr, r, c, [&]() {
|
||||||
|
if constexpr (!std::same_as<Stride, stride>)
|
||||||
|
return strides<storage_order>(Stride{}, r, c);
|
||||||
else return strides<storage_order>(r, c);
|
else return strides<storage_order>(r, c);
|
||||||
}()
|
}())
|
||||||
)
|
{
|
||||||
{}
|
}
|
||||||
|
|
||||||
map(ptr_type ptr, stride_type s) requires(RowsAtCompileTime!=-1 && ColsAtCompileTime!=-1)
|
map(ptr_type ptr, stride_type s)
|
||||||
: parent(ptr, strides<storage_order>(s,RowsAtCompileTime,ColsAtCompileTime))
|
requires(RowsAtCompileTime != -1 && ColsAtCompileTime != -1)
|
||||||
{}
|
: parent(ptr,
|
||||||
|
strides<storage_order>(s, RowsAtCompileTime, ColsAtCompileTime))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
map(ptr_type ptr, Index sz) requires(RowsAtCompileTime==1 || ColsAtCompileTime==1)
|
map(ptr_type ptr, Index sz)
|
||||||
: map(ptr, RowsAtCompileTime==1?1:sz, ColsAtCompileTime==1?1:sz)
|
requires(RowsAtCompileTime == 1 || ColsAtCompileTime == 1)
|
||||||
{}
|
: map(
|
||||||
|
ptr, RowsAtCompileTime == 1 ? 1 : sz, ColsAtCompileTime == 1 ? 1 : sz)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
map(ptr_type ptr) requires(RowsAtCompileTime!=-1 && ColsAtCompileTime!=-1)
|
map(ptr_type ptr)
|
||||||
|
requires(RowsAtCompileTime != -1 && ColsAtCompileTime != -1)
|
||||||
: map(ptr, RowsAtCompileTime, ColsAtCompileTime)
|
: map(ptr, RowsAtCompileTime, ColsAtCompileTime)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
map(concepts::entity auto const& other) : parent(other.base())
|
map(concepts::entity auto const& other) : parent(other.base()) {}
|
||||||
{}
|
|
||||||
|
|
||||||
map& operator=(concepts::entity auto const& other)
|
map& operator=(concepts::entity auto const& other)
|
||||||
{
|
{
|
||||||
|
|
@ -93,7 +106,8 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
parent& base() { return static_cast<parent&>(*this); }
|
parent& base() { return static_cast<parent&>(*this); }
|
||||||
parent const& base() const { return static_cast<const parent&>(*this); }
|
|
||||||
|
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||||
|
|
||||||
auto evaluate() const
|
auto evaluate() const
|
||||||
{
|
{
|
||||||
|
|
@ -113,41 +127,57 @@ namespace rotgen
|
||||||
else return *this;
|
else return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator()(Index i, Index j) requires(!is_immutable)
|
value_type& operator()(Index i, Index j)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
return base()(i, j);
|
return base()(i, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
|
value_type& operator()(Index i)
|
||||||
|
requires(!is_immutable && IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return base().data()[i];
|
return base().data()[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator[](Index i) requires(!is_immutable && IsVectorAtCompileTime)
|
value_type& operator[](Index i)
|
||||||
|
requires(!is_immutable && IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return (*this)(i);
|
return (*this)(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type operator()(Index i, Index j) const { return base()(i, j); }
|
value_type operator()(Index i, Index j) const { return base()(i, j); }
|
||||||
value_type operator()(Index i) const requires(IsVectorAtCompileTime) { return base().data()[i]; }
|
|
||||||
value_type operator[](Index i) const requires(IsVectorAtCompileTime) { return (*this)(i); }
|
value_type operator()(Index i) const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
|
{
|
||||||
|
return base().data()[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type operator[](Index i) const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
|
{
|
||||||
|
return (*this)(i);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename R2, int O2, typename S2>
|
template<typename R2, int O2, typename S2>
|
||||||
map& operator+=(map<R2,O2,S2> const& rhs) requires(!is_immutable)
|
map& operator+=(map<R2, O2, S2> const& rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() += rhs.base();
|
base() += rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R2, int O2, typename S2>
|
template<typename R2, int O2, typename S2>
|
||||||
map& operator-=(map<R2,O2,S2> const& rhs) requires(!is_immutable)
|
map& operator-=(map<R2, O2, S2> const& rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() -= rhs.base();
|
base() -= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R2, int O2, typename S2>
|
template<typename R2, int O2, typename S2>
|
||||||
map& operator*=(map<R2,O2,S2> const& rhs) requires(!is_immutable)
|
map& operator*=(map<R2, O2, S2> const& rhs)
|
||||||
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() *= rhs.base();
|
base() *= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -167,106 +197,128 @@ namespace rotgen
|
||||||
|
|
||||||
auto cwiseMin(map const& rhs) const
|
auto cwiseMin(map const& rhs) const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseMin(rhs.base())};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseMin(rhs.base())};
|
||||||
else return base().cwiseMin(rhs.base());
|
else return base().cwiseMin(rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseMin(value_type rhs) const
|
auto cwiseMin(value_type rhs) const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseMin(rhs)};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseMin(rhs)};
|
||||||
else return base().cwiseMin(rhs);
|
else return base().cwiseMin(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseMax(map const& rhs) const
|
auto cwiseMax(map const& rhs) const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseMax(rhs.base())};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseMax(rhs.base())};
|
||||||
else return base().cwiseMax(rhs.base());
|
else return base().cwiseMax(rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseMax(value_type rhs) const
|
auto cwiseMax(value_type rhs) const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseMax(rhs)};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseMax(rhs)};
|
||||||
else return base().cwiseMax(rhs);
|
else return base().cwiseMax(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseProduct(map const& rhs) const
|
auto cwiseProduct(map const& rhs) const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseProduct(rhs.base())};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseProduct(rhs.base())};
|
||||||
else return base().cwiseProduct(rhs.base());
|
else return base().cwiseProduct(rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseQuotient(map const& rhs) const
|
auto cwiseQuotient(map const& rhs) const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseQuotient(rhs.base())};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseQuotient(rhs.base())};
|
||||||
else return base().cwiseQuotient(rhs.base());
|
else return base().cwiseQuotient(rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseAbs() const
|
auto cwiseAbs() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseAbs()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseAbs()};
|
||||||
else return base().cwiseAbs();
|
else return base().cwiseAbs();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseAbs2() const
|
auto cwiseAbs2() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseAbs2()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseAbs2()};
|
||||||
else return base().cwiseAbs2();
|
else return base().cwiseAbs2();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseInverse() const
|
auto cwiseInverse() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseInverse()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseInverse()};
|
||||||
else return base().cwiseInverse();
|
else return base().cwiseInverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseSqrt() const
|
auto cwiseSqrt() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseSqrt()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cwiseSqrt()};
|
||||||
else return base().cwiseSqrt();
|
else return base().cwiseSqrt();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cross(map const& rhs) const
|
auto cross(map const& rhs) const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return concrete_type{parent::cross(rhs.base())};
|
if constexpr (!use_expression_templates)
|
||||||
|
return concrete_type{parent::cross(rhs.base())};
|
||||||
else return base().cross(rhs.base());
|
else return base().cross(rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto inverse() const
|
auto inverse() const
|
||||||
{
|
{
|
||||||
if constexpr (use_expression_templates) return base().inverse();
|
if constexpr (use_expression_templates) return base().inverse();
|
||||||
else return as_concrete_type<decltype(base().inverse())>(base().inverse());
|
else
|
||||||
|
return as_concrete_type<decltype(base().inverse())>(base().inverse());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto normalized() const requires(IsVectorAtCompileTime)
|
auto normalized() const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
if constexpr (use_expression_templates) return base().normalized();
|
if constexpr (use_expression_templates) return base().normalized();
|
||||||
else return as_concrete_type<decltype(base().normalized())>(base().normalized());
|
else
|
||||||
|
return as_concrete_type<decltype(base().normalized())>(
|
||||||
|
base().normalized());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto transpose() const
|
auto transpose() const
|
||||||
{
|
{
|
||||||
if constexpr (use_expression_templates) return base().transpose();
|
if constexpr (use_expression_templates) return base().transpose();
|
||||||
else return as_concrete_type<decltype(base().transpose())>(base().transpose());
|
else
|
||||||
|
return as_concrete_type<decltype(base().transpose())>(
|
||||||
|
base().transpose());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto adjoint() const
|
auto adjoint() const
|
||||||
{
|
{
|
||||||
if constexpr (use_expression_templates) return base().adjoint();
|
if constexpr (use_expression_templates) return base().adjoint();
|
||||||
else return as_concrete_type<decltype(base().adjoint())>(base().adjoint());
|
else
|
||||||
|
return as_concrete_type<decltype(base().adjoint())>(base().adjoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto conjugate() const
|
auto conjugate() const
|
||||||
{
|
{
|
||||||
if constexpr (use_expression_templates) return base().conjugate();
|
if constexpr (use_expression_templates) return base().conjugate();
|
||||||
else return as_concrete_type<decltype(base().conjugate())>(base().conjugate());
|
else
|
||||||
|
return as_concrete_type<decltype(base().conjugate())>(
|
||||||
|
base().conjugate());
|
||||||
}
|
}
|
||||||
|
|
||||||
void normalize() requires(IsVectorAtCompileTime)
|
void normalize()
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
base().normalize();
|
base().normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void transposeInPlace() { base().transposeInPlace(); }
|
void transposeInPlace() { base().transposeInPlace(); }
|
||||||
|
|
||||||
void adjointInPlace() { base().adjointInPlace(); }
|
void adjointInPlace() { base().adjointInPlace(); }
|
||||||
|
|
||||||
auto qr_solve(auto const& rhs) const
|
auto qr_solve(auto const& rhs) const
|
||||||
|
|
@ -274,22 +326,51 @@ namespace rotgen
|
||||||
return concrete_type(base().colPivHouseholderQr().solve(rhs.base()));
|
return concrete_type(base().colPivHouseholderQr().solve(rhs.base()));
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto Zero() requires( requires {Ref::Zero();} ) { return Ref::Zero(); }
|
static auto Zero()
|
||||||
|
requires(requires { Ref::Zero(); })
|
||||||
|
{
|
||||||
|
return Ref::Zero();
|
||||||
|
}
|
||||||
|
|
||||||
static auto Zero(int rows, int cols) { return Ref::Zero(rows, cols); }
|
static auto Zero(int rows, int cols) { return Ref::Zero(rows, cols); }
|
||||||
|
|
||||||
static auto Ones() requires( requires {Ref::Ones();} ) { return Ref::Ones(); }
|
static auto Ones()
|
||||||
|
requires(requires { Ref::Ones(); })
|
||||||
|
{
|
||||||
|
return Ref::Ones();
|
||||||
|
}
|
||||||
|
|
||||||
static auto Ones(int rows, int cols) { return Ref::Ones(rows, cols); }
|
static auto Ones(int rows, int cols) { return Ref::Ones(rows, cols); }
|
||||||
|
|
||||||
static auto Constant(value_type value) requires( requires {Ref::Constant(value);} )
|
static auto Constant(value_type value)
|
||||||
{ return Ref::Constant(value); }
|
requires(requires { Ref::Constant(value); })
|
||||||
|
{
|
||||||
|
return Ref::Constant(value);
|
||||||
|
}
|
||||||
|
|
||||||
static auto Constant(int rows, int cols, value_type value) { return Ref::Constant(rows, cols, value); }
|
static auto Constant(int rows, int cols, value_type value)
|
||||||
|
{
|
||||||
|
return Ref::Constant(rows, cols, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto Random()
|
||||||
|
requires(requires { Ref::Random(); })
|
||||||
|
{
|
||||||
|
return Ref::Random();
|
||||||
|
}
|
||||||
|
|
||||||
static auto Random() requires( requires {Ref::Random();} ) { return Ref::Random(); }
|
|
||||||
static auto Random(int rows, int cols) { return Ref::Random(rows, cols); }
|
static auto Random(int rows, int cols) { return Ref::Random(rows, cols); }
|
||||||
|
|
||||||
static auto Identity() requires( requires {Ref::Identity();} ) { return Ref::Identity(); }
|
static auto Identity()
|
||||||
static auto Identity(int rows, int cols) { return Ref::Identity(rows, cols); }
|
requires(requires { Ref::Identity(); })
|
||||||
|
{
|
||||||
|
return Ref::Identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto Identity(int rows, int cols)
|
||||||
|
{
|
||||||
|
return Ref::Identity(rows, cols);
|
||||||
|
}
|
||||||
|
|
||||||
map& setOnes()
|
map& setOnes()
|
||||||
{
|
{
|
||||||
|
|
@ -321,21 +402,21 @@ namespace rotgen
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
using parent::innerStride;
|
|
||||||
using parent::outerStride;
|
|
||||||
using parent::rows;
|
|
||||||
using parent::cols;
|
using parent::cols;
|
||||||
using parent::size;
|
|
||||||
using parent::data;
|
using parent::data;
|
||||||
using parent::sum;
|
using parent::innerStride;
|
||||||
using parent::mean;
|
using parent::mean;
|
||||||
using parent::prod;
|
|
||||||
using parent::trace;
|
|
||||||
using parent::norm;
|
using parent::norm;
|
||||||
|
using parent::outerStride;
|
||||||
|
using parent::prod;
|
||||||
|
using parent::rows;
|
||||||
|
using parent::size;
|
||||||
using parent::squaredNorm;
|
using parent::squaredNorm;
|
||||||
|
using parent::sum;
|
||||||
|
using parent::trace;
|
||||||
|
|
||||||
auto minCoeff() const { return parent::minCoeff(); }
|
auto minCoeff() const { return parent::minCoeff(); }
|
||||||
|
|
||||||
auto maxCoeff() const { return parent::maxCoeff(); }
|
auto maxCoeff() const { return parent::maxCoeff(); }
|
||||||
|
|
||||||
template<std::integral IndexType>
|
template<std::integral IndexType>
|
||||||
|
|
@ -403,32 +484,37 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, int O, typename S>
|
template<typename R, int O, typename S>
|
||||||
auto operator*( map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s)
|
auto operator*(map<R, O, S> const& lhs,
|
||||||
|
std::convertible_to<typename R::value_type> auto s)
|
||||||
{
|
{
|
||||||
return lhs.base() * s;
|
return lhs.base() * s;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, int O, typename S>
|
template<typename R, int O, typename S>
|
||||||
auto operator*(std::convertible_to<typename R::value_type> auto s, map<R, O, S> const& rhs)
|
auto operator*(std::convertible_to<typename R::value_type> auto s,
|
||||||
|
map<R, O, S> const& rhs)
|
||||||
{
|
{
|
||||||
return s * rhs.base();
|
return s * rhs.base();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, int O, typename S>
|
template<typename R, int O, typename S>
|
||||||
auto operator/(map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s)
|
auto operator/(map<R, O, S> const& lhs,
|
||||||
|
std::convertible_to<typename R::value_type> auto s)
|
||||||
{
|
{
|
||||||
return lhs.base() / s;
|
return lhs.base() / s;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
||||||
typename map<R1,O1,S1>::concrete_type operator+(map<R1, O1, S1> const& lhs, map<R2,O2,S2> const& rhs)
|
typename map<R1, O1, S1>::concrete_type operator+(map<R1, O1, S1> const& lhs,
|
||||||
|
map<R2, O2, S2> const& rhs)
|
||||||
{
|
{
|
||||||
using concrete_type = typename map<R1, O1, S1>::concrete_type;
|
using concrete_type = typename map<R1, O1, S1>::concrete_type;
|
||||||
return concrete_type(lhs.base() + rhs.base());
|
return concrete_type(lhs.base() + rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
||||||
typename map<R1,O1,S1>::concrete_type operator-(map<R1, O1, S1> const& lhs, map<R2,O2,S2> const& rhs)
|
typename map<R1, O1, S1>::concrete_type operator-(map<R1, O1, S1> const& lhs,
|
||||||
|
map<R2, O2, S2> const& rhs)
|
||||||
{
|
{
|
||||||
using concrete_type = typename map<R1, O1, S1>::concrete_type;
|
using concrete_type = typename map<R1, O1, S1>::concrete_type;
|
||||||
return concrete_type(lhs.base() - rhs.base());
|
return concrete_type(lhs.base() - rhs.base());
|
||||||
|
|
@ -438,35 +524,31 @@ namespace rotgen
|
||||||
matrix<typename R1::value_type, R1::RowsAtCompileTime, R2::ColsAtCompileTime>
|
matrix<typename R1::value_type, R1::RowsAtCompileTime, R2::ColsAtCompileTime>
|
||||||
operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
||||||
{
|
{
|
||||||
using concrete_type = matrix< typename R1::value_type
|
using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime,
|
||||||
, R1::RowsAtCompileTime,R2::ColsAtCompileTime
|
R2::ColsAtCompileTime>;
|
||||||
>;
|
|
||||||
|
|
||||||
return concrete_type(lhs.base() * rhs.base());
|
return concrete_type(lhs.base() * rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, int O, typename S>
|
template<typename R, int O, typename S>
|
||||||
typename map<R,O,S>::concrete_type operator*( map<R, O, S> const& lhs
|
typename map<R, O, S>::concrete_type operator*(
|
||||||
, std::convertible_to<typename R::value_type> auto s
|
map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
using concrete_type = typename map<R, O, S>::concrete_type;
|
using concrete_type = typename map<R, O, S>::concrete_type;
|
||||||
return concrete_type(lhs.base() * s);
|
return concrete_type(lhs.base() * s);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, int O, typename S>
|
template<typename R, int O, typename S>
|
||||||
typename map<R,O,S>::concrete_type operator*( std::convertible_to<typename R::value_type> auto s
|
typename map<R, O, S>::concrete_type operator*(
|
||||||
, map<R, O, S> const& rhs
|
std::convertible_to<typename R::value_type> auto s, map<R, O, S> const& rhs)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
using concrete_type = typename map<R, O, S>::concrete_type;
|
using concrete_type = typename map<R, O, S>::concrete_type;
|
||||||
return concrete_type(rhs.base() * s);
|
return concrete_type(rhs.base() * s);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename R, int O, typename S>
|
template<typename R, int O, typename S>
|
||||||
typename map<R,O,S>::concrete_type operator/( map<R, O, S> const& lhs
|
typename map<R, O, S>::concrete_type operator/(
|
||||||
, std::convertible_to<typename R::value_type> auto s
|
map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
using concrete_type = typename map<R, O, S>::concrete_type;
|
using concrete_type = typename map<R, O, S>::concrete_type;
|
||||||
return concrete_type(lhs.base() / s);
|
return concrete_type(lhs.base() / s);
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,12 @@
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
template< typename Scalar
|
template<typename Scalar,
|
||||||
, int Rows = Dynamic , int Cols = Dynamic
|
int Rows = Dynamic,
|
||||||
, int Opts = detail::force_order<Rows,Cols>
|
int Cols = Dynamic,
|
||||||
, int MaxRows = Rows , int MaxCols = Cols
|
int Opts = detail::force_order<Rows, Cols>,
|
||||||
>
|
int MaxRows = Rows,
|
||||||
|
int MaxCols = Cols>
|
||||||
class matrix : public find_matrix<Scalar, Opts>
|
class matrix : public find_matrix<Scalar, Opts>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -33,7 +34,8 @@ namespace rotgen
|
||||||
static constexpr int MaxRowsAtCompileTime = MaxRows;
|
static constexpr int MaxRowsAtCompileTime = MaxRows;
|
||||||
static constexpr int MaxColsAtCompileTime = MaxCols;
|
static constexpr int MaxColsAtCompileTime = MaxCols;
|
||||||
static constexpr bool IsCompileTimeSized = Rows != -1 && Cols != -1;
|
static constexpr bool IsCompileTimeSized = Rows != -1 && Cols != -1;
|
||||||
static constexpr bool IsVectorAtCompileTime = (RowsAtCompileTime == 1) || (ColsAtCompileTime == 1);
|
static constexpr bool IsVectorAtCompileTime =
|
||||||
|
(RowsAtCompileTime == 1) || (ColsAtCompileTime == 1);
|
||||||
static constexpr int Options = Opts;
|
static constexpr int Options = Opts;
|
||||||
static constexpr bool IsRowMajor = (Opts & RowMajor) == RowMajor;
|
static constexpr bool IsRowMajor = (Opts & RowMajor) == RowMajor;
|
||||||
static constexpr bool is_defined_static = false;
|
static constexpr bool is_defined_static = false;
|
||||||
|
|
@ -44,85 +46,116 @@ namespace rotgen
|
||||||
|
|
||||||
matrix() : parent(Rows == -1 ? 0 : Rows, Cols == -1 ? 0 : Cols) {}
|
matrix() : parent(Rows == -1 ? 0 : Rows, Cols == -1 ? 0 : Cols) {}
|
||||||
|
|
||||||
matrix(Index r, Index c) requires(!IsCompileTimeSized)
|
matrix(Index r, Index c)
|
||||||
|
requires(!IsCompileTimeSized)
|
||||||
: parent(r, c)
|
: parent(r, c)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(r == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(c == Cols && "Mismatched between dynamic and static column size");
|
assert(r == Rows && "Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(c == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix(Index n) requires(IsVectorAtCompileTime && (Rows != 1 || Cols != 1))
|
matrix(Index n)
|
||||||
|
requires(IsVectorAtCompileTime && (Rows != 1 || Cols != 1))
|
||||||
: parent(Rows != -1 ? 1 : n, Cols != -1 ? 1 : n)
|
: parent(Rows != -1 ? 1 : n, Cols != -1 ? 1 : n)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
matrix(Scalar v) requires(Rows == 1 && Cols == 1) : parent(1,1,{v}) {}
|
matrix(Scalar v)
|
||||||
|
requires(Rows == 1 && Cols == 1)
|
||||||
|
: parent(1, 1, {v})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
matrix(Scalar v0, Scalar v1, auto... vs)
|
matrix(Scalar v0, Scalar v1, auto... vs)
|
||||||
requires((Rows == (2+sizeof...(vs)) && Cols == 1) || (Rows == 1 && Cols == (2+sizeof...(vs))))
|
requires((Rows == (2 + sizeof...(vs)) && Cols == 1) ||
|
||||||
|
(Rows == 1 && Cols == (2 + sizeof...(vs))))
|
||||||
: parent(Rows, Cols, {v0, v1, static_cast<Scalar>(vs)...})
|
: parent(Rows, Cols, {v0, v1, static_cast<Scalar>(vs)...})
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
matrix(parent const& base) : parent(base) {}
|
matrix(parent const& base) : parent(base) {}
|
||||||
|
|
||||||
matrix(std::initializer_list<std::initializer_list<Scalar>> init) : parent(init)
|
matrix(std::initializer_list<std::initializer_list<Scalar>> init)
|
||||||
|
: parent(init)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(init.size() == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
|
assert(init.size() == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
{
|
{
|
||||||
[[maybe_unused]] std::size_t c = 0;
|
[[maybe_unused]] std::size_t c = 0;
|
||||||
if (init.size()) c = init.begin()->size();
|
if (init.size()) c = init.begin()->size();
|
||||||
assert(c == Cols && "Mismatched between dynamic and static column size");
|
assert(c == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix(std::initializer_list<Scalar> init)
|
matrix(std::initializer_list<Scalar> init)
|
||||||
requires(IsVectorAtCompileTime) : parent(Rows, Cols, init)
|
requires(IsVectorAtCompileTime)
|
||||||
{}
|
: parent(Rows, Cols, init)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
matrix(concepts::entity auto const& e) : parent(e.rows(), e.cols())
|
matrix(concepts::entity auto const& e) : parent(e.rows(), e.cols())
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(e.rows() == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(e.cols() == Cols && "Mismatched between dynamic and static col size");
|
assert(e.rows() == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(e.cols() == Cols &&
|
||||||
|
"Mismatched between dynamic and static col size");
|
||||||
for (rotgen::Index r = 0; r < e.rows(); ++r)
|
for (rotgen::Index r = 0; r < e.rows(); ++r)
|
||||||
for (rotgen::Index c = 0; c < e.cols(); ++c)
|
for (rotgen::Index c = 0; c < e.cols(); ++c) (*this)(r, c) = e(r, c);
|
||||||
(*this)(r, c) = e(r, c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix& operator=(concepts::entity auto const& e)
|
matrix& operator=(concepts::entity auto const& e)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(e.rows() == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(e.cols() == Cols && "Mismatched between dynamic and static col size");
|
assert(e.rows() == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(e.cols() == Cols &&
|
||||||
|
"Mismatched between dynamic and static col size");
|
||||||
resize(e.rows(), e.cols());
|
resize(e.rows(), e.cols());
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < e.rows(); ++r)
|
for (rotgen::Index r = 0; r < e.rows(); ++r)
|
||||||
for (rotgen::Index c = 0; c < e.cols(); ++c)
|
for (rotgen::Index c = 0; c < e.cols(); ++c) (*this)(r, c) = e(r, c);
|
||||||
(*this)(r, c) = e(r, c);
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator[](Index i) requires(IsVectorAtCompileTime)
|
value_type& operator[](Index i)
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return (*this)(i);
|
return (*this)(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type operator[](Index i) const requires(IsVectorAtCompileTime)
|
value_type operator[](Index i) const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return (*this)(i);
|
return (*this)(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto evaluate() const { return *this; }
|
auto evaluate() const { return *this; }
|
||||||
|
|
||||||
decltype(auto) noalias() const { return *this; }
|
decltype(auto) noalias() const { return *this; }
|
||||||
|
|
||||||
decltype(auto) noalias() { return *this; }
|
decltype(auto) noalias() { return *this; }
|
||||||
|
|
||||||
void resize(int r, int c)
|
void resize(int r, int c)
|
||||||
{
|
{
|
||||||
if constexpr(Rows == 1) assert(c == Cols && "Mismatched between dynamic and static col size");
|
if constexpr (Rows == 1)
|
||||||
if constexpr(Cols == 1) assert(r == Rows && "Mismatched between dynamic and static row size");
|
assert(c == Cols && "Mismatched between dynamic and static col size");
|
||||||
|
if constexpr (Cols == 1)
|
||||||
|
assert(r == Rows && "Mismatched between dynamic and static row size");
|
||||||
parent::resize(r, c);
|
parent::resize(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(int s) requires(IsVectorAtCompileTime)
|
void resize(int s)
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
if constexpr (Rows == 1) parent::resize(1, s);
|
if constexpr (Rows == 1) parent::resize(1, s);
|
||||||
else parent::resize(s, 1);
|
else parent::resize(s, 1);
|
||||||
|
|
@ -130,18 +163,22 @@ namespace rotgen
|
||||||
|
|
||||||
void conservativeResize(int r, int c)
|
void conservativeResize(int r, int c)
|
||||||
{
|
{
|
||||||
if constexpr(Rows == 1) assert(c == Cols && "Mismatched between dynamic and static col size");
|
if constexpr (Rows == 1)
|
||||||
if constexpr(Cols == 1) assert(r == Rows && "Mismatched between dynamic and static row size");
|
assert(c == Cols && "Mismatched between dynamic and static col size");
|
||||||
|
if constexpr (Cols == 1)
|
||||||
|
assert(r == Rows && "Mismatched between dynamic and static row size");
|
||||||
parent::conservativeResize(r, c);
|
parent::conservativeResize(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void conservativeResize(int s) requires(IsVectorAtCompileTime)
|
void conservativeResize(int s)
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
if constexpr (Rows == 1) parent::conservativeResize(1, s);
|
if constexpr (Rows == 1) parent::conservativeResize(1, s);
|
||||||
else parent::conservativeResize(s, 1);
|
else parent::conservativeResize(s, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix normalized() const requires(IsVectorAtCompileTime)
|
matrix normalized() const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return matrix(base().normalized());
|
return matrix(base().normalized());
|
||||||
}
|
}
|
||||||
|
|
@ -151,27 +188,29 @@ namespace rotgen
|
||||||
return transposed_type(base().transpose());
|
return transposed_type(base().transpose());
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix conjugate() const
|
matrix conjugate() const { return matrix(base().conjugate()); }
|
||||||
{
|
|
||||||
return matrix(base().conjugate());
|
|
||||||
}
|
|
||||||
|
|
||||||
transposed_type adjoint() const
|
transposed_type adjoint() const
|
||||||
{
|
{
|
||||||
return transposed_type(base().adjoint());
|
return transposed_type(base().adjoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
void normalize() requires(IsVectorAtCompileTime)
|
void normalize()
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
parent::normalize();
|
parent::normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void transposeInPlace() { parent::transposeInPlace(); }
|
void transposeInPlace() { parent::transposeInPlace(); }
|
||||||
|
|
||||||
void adjointInPlace() { parent::adjointInPlace(); }
|
void adjointInPlace() { parent::adjointInPlace(); }
|
||||||
|
|
||||||
matrix cwiseAbs() const { return matrix(base().cwiseAbs()); }
|
matrix cwiseAbs() const { return matrix(base().cwiseAbs()); }
|
||||||
|
|
||||||
matrix cwiseAbs2() const { return matrix(base().cwiseAbs2()); }
|
matrix cwiseAbs2() const { return matrix(base().cwiseAbs2()); }
|
||||||
|
|
||||||
matrix cwiseInverse() const { return matrix(base().cwiseInverse()); }
|
matrix cwiseInverse() const { return matrix(base().cwiseInverse()); }
|
||||||
|
|
||||||
matrix cwiseSqrt() const { return matrix(base().cwiseSqrt()); }
|
matrix cwiseSqrt() const { return matrix(base().cwiseSqrt()); }
|
||||||
|
|
||||||
friend bool operator==(matrix const& lhs, matrix const& rhs)
|
friend bool operator==(matrix const& lhs, matrix const& rhs)
|
||||||
|
|
@ -191,10 +230,7 @@ namespace rotgen
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix operator-() const
|
matrix operator-() const { return matrix(base().operator-()); }
|
||||||
{
|
|
||||||
return matrix(base().operator-());
|
|
||||||
}
|
|
||||||
|
|
||||||
matrix& operator*=(matrix const& rhs)
|
matrix& operator*=(matrix const& rhs)
|
||||||
{
|
{
|
||||||
|
|
@ -215,6 +251,7 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
auto minCoeff() const { return parent::minCoeff(); }
|
auto minCoeff() const { return parent::minCoeff(); }
|
||||||
|
|
||||||
auto maxCoeff() const { return parent::maxCoeff(); }
|
auto maxCoeff() const { return parent::maxCoeff(); }
|
||||||
|
|
||||||
template<std::integral IndexType>
|
template<std::integral IndexType>
|
||||||
|
|
@ -237,63 +274,88 @@ namespace rotgen
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Ones() requires (Rows != -1 && Cols != -1)
|
static matrix Ones()
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Ones(Rows, Cols);
|
return parent::Ones(Rows, Cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Ones(int rows, int cols)
|
static matrix Ones(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Ones(rows, cols);
|
return parent::Ones(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Zero() requires (Rows != -1 && Cols != -1)
|
static matrix Zero()
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Zero(Rows, Cols);
|
return parent::Zero(Rows, Cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Zero(int rows, int cols)
|
static matrix Zero(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Zero(rows, cols);
|
return parent::Zero(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Constant(Scalar value) requires (Rows != -1 && Cols != -1)
|
static matrix Constant(Scalar value)
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Constant(Rows, Cols, static_cast<Scalar>(value));
|
return parent::Constant(Rows, Cols, static_cast<Scalar>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Constant(int rows, int cols, Scalar value)
|
static matrix Constant(int rows, int cols, Scalar value)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Constant(rows, cols, static_cast<Scalar>(value));
|
return parent::Constant(rows, cols, static_cast<Scalar>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Random() requires (Rows != -1 && Cols != -1)
|
static matrix Random()
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Random(Rows, Cols);
|
return parent::Random(Rows, Cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Random(int rows, int cols)
|
static matrix Random(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Random(rows, cols);
|
return parent::Random(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Identity() requires (Rows != -1 && Cols != -1)
|
static matrix Identity()
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Identity(Rows, Cols);
|
return parent::Identity(Rows, Cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Identity(int rows, int cols)
|
static matrix Identity(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Identity(rows, cols);
|
return parent::Identity(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,7 +385,8 @@ namespace rotgen
|
||||||
|
|
||||||
matrix& setConstant(Scalar value)
|
matrix& setConstant(Scalar value)
|
||||||
{
|
{
|
||||||
*this = parent::Constant(parent::rows(), parent::cols(), static_cast<Scalar>(value));
|
*this = parent::Constant(parent::rows(), parent::cols(),
|
||||||
|
static_cast<Scalar>(value));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -357,53 +420,63 @@ namespace rotgen
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int P>
|
template<int P> Scalar lpNorm() const
|
||||||
Scalar lpNorm() const
|
|
||||||
{
|
{
|
||||||
static_assert(P == 1 || P == 2 || P == Infinity);
|
static_assert(P == 1 || P == 2 || P == Infinity);
|
||||||
return parent::lp_norm(P);
|
return parent::lp_norm(P);
|
||||||
}
|
}
|
||||||
|
|
||||||
parent& base() { return static_cast<parent&>(*this); }
|
parent& base() { return static_cast<parent&>(*this); }
|
||||||
parent const& base() const { return static_cast<parent const&>(*this);; }
|
|
||||||
|
parent const& base() const
|
||||||
|
{
|
||||||
|
return static_cast<parent const&>(*this);
|
||||||
|
;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename S, int R, int C, int O, int MR, int MC>
|
template<typename S, int R, int C, int O, int MR, int MC>
|
||||||
matrix<S,R,C,O,MR,MC> operator+(matrix<S,R,C,O,MR,MC> const& lhs, matrix<S,R,C,O,MR,MC> const& rhs)
|
matrix<S, R, C, O, MR, MC> operator+(matrix<S, R, C, O, MR, MC> const& lhs,
|
||||||
|
matrix<S, R, C, O, MR, MC> const& rhs)
|
||||||
{
|
{
|
||||||
matrix<S, R, C, O, MR, MC> that(lhs);
|
matrix<S, R, C, O, MR, MC> that(lhs);
|
||||||
return that += rhs;
|
return that += rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename S, int R, int C, int O, int MR, int MC>
|
template<typename S, int R, int C, int O, int MR, int MC>
|
||||||
matrix<S,R,C,O,MR,MC> operator-(matrix<S,R,C,O,MR,MC> const& lhs, matrix<S,R,C,O,MR,MC> const& rhs)
|
matrix<S, R, C, O, MR, MC> operator-(matrix<S, R, C, O, MR, MC> const& lhs,
|
||||||
|
matrix<S, R, C, O, MR, MC> const& rhs)
|
||||||
{
|
{
|
||||||
matrix<S, R, C, O, MR, MC> that(lhs);
|
matrix<S, R, C, O, MR, MC> that(lhs);
|
||||||
return that -= rhs;
|
return that -= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename S, int R, int C, int O, int MR, int MC>
|
template<typename S, int R, int C, int O, int MR, int MC>
|
||||||
matrix<S,R,C,O,MR,MC> operator*(matrix<S,R,C,O,MR,MC> const& lhs, matrix<S,R,C,O,MR,MC> const& rhs)
|
matrix<S, R, C, O, MR, MC> operator*(matrix<S, R, C, O, MR, MC> const& lhs,
|
||||||
|
matrix<S, R, C, O, MR, MC> const& rhs)
|
||||||
{
|
{
|
||||||
matrix<S, R, C, O, MR, MC> that(lhs);
|
matrix<S, R, C, O, MR, MC> that(lhs);
|
||||||
return that *= rhs;
|
return that *= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename S, int R, int C, int O, int MR, int MC>
|
template<typename S, int R, int C, int O, int MR, int MC>
|
||||||
matrix<S,R,C,O,MR,MC> operator*(matrix<S,R,C,O,MR,MC> const& lhs, double rhs)
|
matrix<S, R, C, O, MR, MC> operator*(matrix<S, R, C, O, MR, MC> const& lhs,
|
||||||
|
double rhs)
|
||||||
{
|
{
|
||||||
matrix<S, R, C, O, MR, MC> that(lhs);
|
matrix<S, R, C, O, MR, MC> that(lhs);
|
||||||
return that *= rhs;
|
return that *= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename S, int R, int C, int O, int MR, int MC>
|
template<typename S, int R, int C, int O, int MR, int MC>
|
||||||
matrix<S,R,C,O,MR,MC> operator*(double lhs, matrix<S,R,C,O,MR,MC> const& rhs)
|
matrix<S, R, C, O, MR, MC> operator*(double lhs,
|
||||||
|
matrix<S, R, C, O, MR, MC> const& rhs)
|
||||||
{
|
{
|
||||||
return rhs * lhs;
|
return rhs * lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename S, int R, int C, int O, int MR, int MC>
|
template<typename S, int R, int C, int O, int MR, int MC>
|
||||||
matrix<S,R,C,O,MR,MC> operator/(matrix<S,R,C,O,MR,MC> const& lhs, double rhs)
|
matrix<S, R, C, O, MR, MC> operator/(matrix<S, R, C, O, MR, MC> const& lhs,
|
||||||
|
double rhs)
|
||||||
{
|
{
|
||||||
matrix<S, R, C, O, MR, MC> that(lhs);
|
matrix<S, R, C, O, MR, MC> that(lhs);
|
||||||
return that /= rhs;
|
return that /= rhs;
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,25 @@ namespace rotgen
|
||||||
|
|
||||||
template<typename Scalar, int Options> struct find_matrix_impl;
|
template<typename Scalar, int Options> struct find_matrix_impl;
|
||||||
|
|
||||||
template<> struct find_matrix_impl<float , ColMajor> { using type = matrix_impl32_col; };
|
template<> struct find_matrix_impl<float, ColMajor>
|
||||||
template<> struct find_matrix_impl<float , RowMajor> { using type = matrix_impl32_row; };
|
{
|
||||||
template<> struct find_matrix_impl<double, ColMajor> { using type = matrix_impl64_col; };
|
using type = matrix_impl32_col;
|
||||||
template<> struct find_matrix_impl<double, RowMajor> { using type = matrix_impl64_row; };
|
};
|
||||||
|
|
||||||
|
template<> struct find_matrix_impl<float, RowMajor>
|
||||||
|
{
|
||||||
|
using type = matrix_impl32_row;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_matrix_impl<double, ColMajor>
|
||||||
|
{
|
||||||
|
using type = matrix_impl64_col;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct find_matrix_impl<double, RowMajor>
|
||||||
|
{
|
||||||
|
using type = matrix_impl64_row;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename Scalar, int Options>
|
template<typename Scalar, int Options>
|
||||||
using find_matrix = typename find_matrix_impl<Scalar, (Options & 1)>::type;
|
using find_matrix = typename find_matrix_impl<Scalar, (Options & 1)>::type;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,9 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
public:
|
public:
|
||||||
CLASSNAME();
|
CLASSNAME();
|
||||||
CLASSNAME(std::size_t rows, std::size_t cols);
|
CLASSNAME(std::size_t rows, std::size_t cols);
|
||||||
CLASSNAME(std::size_t rows, std::size_t cols,std::initializer_list<TYPE> init);
|
CLASSNAME(std::size_t rows,
|
||||||
|
std::size_t cols,
|
||||||
|
std::initializer_list<TYPE> init);
|
||||||
|
|
||||||
CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init);
|
CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init);
|
||||||
|
|
||||||
|
|
@ -75,10 +77,14 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
CLASSNAME& operator*=(TYPE d);
|
CLASSNAME& operator*=(TYPE d);
|
||||||
CLASSNAME& operator/=(TYPE d);
|
CLASSNAME& operator/=(TYPE d);
|
||||||
|
|
||||||
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&,CLASSNAME const&);
|
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&,
|
||||||
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&, format<CLASSNAME> const&);
|
CLASSNAME const&);
|
||||||
friend ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs);
|
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&,
|
||||||
friend ROTGEN_EXPORT bool operator!=(CLASSNAME const& lhs, CLASSNAME const& rhs);
|
format<CLASSNAME> const&);
|
||||||
|
friend ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs,
|
||||||
|
CLASSNAME const& rhs);
|
||||||
|
friend ROTGEN_EXPORT bool operator!=(CLASSNAME const& lhs,
|
||||||
|
CLASSNAME const& rhs);
|
||||||
|
|
||||||
const TYPE* data() const;
|
const TYPE* data() const;
|
||||||
TYPE* data();
|
TYPE* data();
|
||||||
|
|
@ -95,5 +101,6 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<payload>& storage() { return storage_; }
|
std::unique_ptr<payload>& storage() { return storage_; }
|
||||||
|
|
||||||
std::unique_ptr<payload> const& storage() const { return storage_; }
|
std::unique_ptr<payload> const& storage() const { return storage_; }
|
||||||
};
|
};
|
||||||
|
|
@ -15,23 +15,31 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename Scalar, int Rows, int Cols, int Opts, int MaxRows, int MaxCols>
|
template<typename Scalar,
|
||||||
using storage_type = std::conditional_t < storage_status<Rows,Cols,MaxRows,MaxCols>
|
int Rows,
|
||||||
, Eigen::Matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>
|
int Cols,
|
||||||
, Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Opts>
|
int Opts,
|
||||||
>;
|
int MaxRows,
|
||||||
|
int MaxCols>
|
||||||
|
using storage_type = std::conditional_t<
|
||||||
|
storage_status<Rows, Cols, MaxRows, MaxCols>,
|
||||||
|
Eigen::Matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>,
|
||||||
|
Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Opts>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename Scalar
|
template<typename Scalar,
|
||||||
, int Rows = Dynamic , int Cols = Dynamic
|
int Rows = Dynamic,
|
||||||
, int Opts = detail::force_order<Rows,Cols>
|
int Cols = Dynamic,
|
||||||
, int MaxRows = Rows, int MaxCols = Cols
|
int Opts = detail::force_order<Rows, Cols>,
|
||||||
>
|
int MaxRows = Rows,
|
||||||
class matrix : private detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>
|
int MaxCols = Cols>
|
||||||
|
class matrix
|
||||||
|
: private detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
using parent = detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
|
using parent =
|
||||||
|
detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
|
||||||
using value_type = Scalar;
|
using value_type = Scalar;
|
||||||
using Index = typename parent::Index;
|
using Index = typename parent::Index;
|
||||||
|
|
||||||
|
|
@ -44,7 +52,8 @@ namespace rotgen
|
||||||
static constexpr int MaxRowsAtCompileTime = MaxRows;
|
static constexpr int MaxRowsAtCompileTime = MaxRows;
|
||||||
static constexpr int MaxColsAtCompileTime = MaxCols;
|
static constexpr int MaxColsAtCompileTime = MaxCols;
|
||||||
static constexpr bool IsCompileTimeSized = Rows != -1 && Cols != -1;
|
static constexpr bool IsCompileTimeSized = Rows != -1 && Cols != -1;
|
||||||
static constexpr bool IsVectorAtCompileTime = (RowsAtCompileTime == 1) || (ColsAtCompileTime == 1);
|
static constexpr bool IsVectorAtCompileTime =
|
||||||
|
(RowsAtCompileTime == 1) || (ColsAtCompileTime == 1);
|
||||||
static constexpr int Options = parent::Options;
|
static constexpr int Options = parent::Options;
|
||||||
static constexpr bool IsRowMajor = parent::IsRowMajor;
|
static constexpr bool IsRowMajor = parent::IsRowMajor;
|
||||||
|
|
||||||
|
|
@ -53,76 +62,92 @@ namespace rotgen
|
||||||
|
|
||||||
static constexpr bool is_immutable = false;
|
static constexpr bool is_immutable = false;
|
||||||
static constexpr bool is_defined_static = Rows != -1 && Cols != -1;
|
static constexpr bool is_defined_static = Rows != -1 && Cols != -1;
|
||||||
static constexpr bool has_static_storage = storage_status<Rows,Cols,MaxRows,MaxCols>;
|
static constexpr bool has_static_storage =
|
||||||
|
storage_status<Rows, Cols, MaxRows, MaxCols>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
matrix()
|
||||||
|
requires(has_static_storage)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
matrix() requires(has_static_storage) {}
|
matrix()
|
||||||
matrix() requires(!has_static_storage) : parent(Rows > 0 ? Rows : 0, Cols > 0 ? Cols : 0){}
|
requires(!has_static_storage)
|
||||||
matrix(Index r, Index c) requires(!IsCompileTimeSized) : parent(r, c) {}
|
: parent(Rows > 0 ? Rows : 0, Cols > 0 ? Cols : 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
matrix(const matrix& other) = default;
|
matrix(Index r, Index c)
|
||||||
|
requires(!IsCompileTimeSized)
|
||||||
|
: parent(r, c)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
matrix(matrix const& other) = default;
|
||||||
matrix(matrix&& other) = default;
|
matrix(matrix&& other) = default;
|
||||||
matrix& operator=(const matrix&) = default;
|
matrix& operator=(matrix const&) = default;
|
||||||
matrix& operator=(matrix&&) = default;
|
matrix& operator=(matrix&&) = default;
|
||||||
|
|
||||||
matrix(std::initializer_list<std::initializer_list<Scalar>> init) : parent(init)
|
matrix(std::initializer_list<std::initializer_list<Scalar>> init)
|
||||||
{}
|
: parent(init)
|
||||||
|
|
||||||
matrix(Index n) requires(IsVectorAtCompileTime && (Rows != 1 || Cols != 1))
|
|
||||||
: parent(n)
|
|
||||||
{}
|
|
||||||
|
|
||||||
matrix(Scalar v) requires(Rows == 1 && Cols == 1) : parent
|
|
||||||
( [&]()
|
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
matrix(Index n)
|
||||||
|
requires(IsVectorAtCompileTime && (Rows != 1 || Cols != 1))
|
||||||
|
: parent(n)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
matrix(Scalar v)
|
||||||
|
requires(Rows == 1 && Cols == 1)
|
||||||
|
: parent([&]() {
|
||||||
if constexpr (has_static_storage) return parent(v);
|
if constexpr (has_static_storage) return parent(v);
|
||||||
else return parent{1, 1};
|
else return parent{1, 1};
|
||||||
}()
|
}())
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if constexpr (!has_static_storage) (*this)(0) = v;
|
if constexpr (!has_static_storage) (*this)(0) = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit matrix(std::initializer_list<Scalar> init)
|
explicit matrix(std::initializer_list<Scalar> init)
|
||||||
requires(IsVectorAtCompileTime)
|
requires(IsVectorAtCompileTime)
|
||||||
: parent( [&]()
|
: parent([&]() {
|
||||||
{
|
|
||||||
if constexpr (has_static_storage) return parent{};
|
if constexpr (has_static_storage) return parent{};
|
||||||
else return parent{Rows, Cols};
|
else return parent{Rows, Cols};
|
||||||
}()
|
}())
|
||||||
)
|
|
||||||
{
|
{
|
||||||
auto first = init.begin();
|
auto first = init.begin();
|
||||||
for(rotgen::Index i=0; i < parent::size(); i++)
|
for (rotgen::Index i = 0; i < parent::size(); i++) (*this)(i) = first[i];
|
||||||
(*this)(i) = first[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix(Scalar v0, Scalar v1, auto... vs)
|
matrix(Scalar v0, Scalar v1, auto... vs)
|
||||||
requires((Rows == (2+sizeof...(vs)) && Cols == 1) || (Rows == 1 && Cols == (2+sizeof...(vs))))
|
requires((Rows == (2 + sizeof...(vs)) && Cols == 1) ||
|
||||||
|
(Rows == 1 && Cols == (2 + sizeof...(vs))))
|
||||||
: matrix({v0, v1, static_cast<Scalar>(vs)...})
|
: matrix({v0, v1, static_cast<Scalar>(vs)...})
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
matrix(concepts::entity auto const& other) : parent(other.base())
|
matrix(concepts::entity auto const& other) : parent(other.base()) {}
|
||||||
{}
|
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
matrix(const Eigen::MatrixBase<OtherDerived>& other) : parent(other)
|
matrix(Eigen::MatrixBase<OtherDerived> const& other) : parent(other)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
matrix(const Eigen::EigenBase<OtherDerived>& other) : parent(other)
|
matrix(Eigen::EigenBase<OtherDerived> const& other) : parent(other)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
matrix& operator=(const Eigen::MatrixBase<OtherDerived>& other)
|
matrix& operator=(Eigen::MatrixBase<OtherDerived> const& other)
|
||||||
{
|
{
|
||||||
parent::operator=(other);
|
parent::operator=(other);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
matrix& operator=(const Eigen::EigenBase<OtherDerived>& other)
|
matrix& operator=(Eigen::EigenBase<OtherDerived> const& other)
|
||||||
{
|
{
|
||||||
parent::operator=(other);
|
parent::operator=(other);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -135,6 +160,7 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
parent& base() { return static_cast<parent&>(*this); }
|
parent& base() { return static_cast<parent&>(*this); }
|
||||||
|
|
||||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||||
|
|
||||||
auto evaluate() const
|
auto evaluate() const
|
||||||
|
|
@ -155,7 +181,8 @@ namespace rotgen
|
||||||
else return *this;
|
else return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto normalized() const requires(IsVectorAtCompileTime)
|
auto normalized() const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
if constexpr (use_expression_templates) return base().normalized();
|
if constexpr (use_expression_templates) return base().normalized();
|
||||||
else
|
else
|
||||||
|
|
@ -187,157 +214,199 @@ namespace rotgen
|
||||||
return as_concrete_type<decltype(res)>(res);
|
return as_concrete_type<decltype(res)>(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void normalize() requires(IsVectorAtCompileTime)
|
void normalize()
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
parent::normalize();
|
parent::normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void transposeInPlace() { parent::transposeInPlace(); }
|
void transposeInPlace() { parent::transposeInPlace(); }
|
||||||
|
|
||||||
void adjointInPlace() { parent::adjointInPlace(); }
|
void adjointInPlace() { parent::adjointInPlace(); }
|
||||||
|
|
||||||
auto cwiseAbs() const
|
auto cwiseAbs() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return matrix{parent::cwiseAbs()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return matrix{parent::cwiseAbs()};
|
||||||
else return base().cwiseAbs();
|
else return base().cwiseAbs();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseAbs2() const
|
auto cwiseAbs2() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return matrix{parent::cwiseAbs2()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return matrix{parent::cwiseAbs2()};
|
||||||
else return base().cwiseAbs2();
|
else return base().cwiseAbs2();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseInverse() const
|
auto cwiseInverse() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return matrix{parent::cwiseInverse()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return matrix{parent::cwiseInverse()};
|
||||||
else return base().cwiseInverse();
|
else return base().cwiseInverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cwiseSqrt() const
|
auto cwiseSqrt() const
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return matrix{parent::cwiseSqrt()};
|
if constexpr (!use_expression_templates)
|
||||||
|
return matrix{parent::cwiseSqrt()};
|
||||||
else return base().cwiseSqrt();
|
else return base().cwiseSqrt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(int s) requires(IsVectorAtCompileTime)
|
void resize(int s)
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
if constexpr(Rows == 1) assert(s == Cols && "Mismatched between dynamic and static col size");
|
if constexpr (Rows == 1)
|
||||||
if constexpr(Cols == 1) assert(s == Rows && "Mismatched between dynamic and static row size");
|
assert(s == Cols && "Mismatched between dynamic and static col size");
|
||||||
|
if constexpr (Cols == 1)
|
||||||
|
assert(s == Rows && "Mismatched between dynamic and static row size");
|
||||||
parent::resize(s);
|
parent::resize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(int r, int c)
|
void resize(int r, int c)
|
||||||
{
|
{
|
||||||
if constexpr(Rows == 1) assert(c == Cols && "Mismatched between dynamic and static col size");
|
if constexpr (Rows == 1)
|
||||||
if constexpr(Cols == 1) assert(r == Rows && "Mismatched between dynamic and static row size");
|
assert(c == Cols && "Mismatched between dynamic and static col size");
|
||||||
|
if constexpr (Cols == 1)
|
||||||
|
assert(r == Rows && "Mismatched between dynamic and static row size");
|
||||||
parent::resize(r, c);
|
parent::resize(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void conservativeResize(int s) requires(IsVectorAtCompileTime)
|
void conservativeResize(int s)
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
if constexpr(Rows == 1) assert(s == Cols && "Mismatched between dynamic and static col size");
|
if constexpr (Rows == 1)
|
||||||
if constexpr(Cols == 1) assert(s == Rows && "Mismatched between dynamic and static row size");
|
assert(s == Cols && "Mismatched between dynamic and static col size");
|
||||||
|
if constexpr (Cols == 1)
|
||||||
|
assert(s == Rows && "Mismatched between dynamic and static row size");
|
||||||
parent::conservativeResize(s);
|
parent::conservativeResize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void conservativeResize(int r, int c)
|
void conservativeResize(int r, int c)
|
||||||
{
|
{
|
||||||
if constexpr(Rows == 1) assert(c == Cols && "Mismatched between dynamic and static col size");
|
if constexpr (Rows == 1)
|
||||||
if constexpr(Cols == 1) assert(r == Rows && "Mismatched between dynamic and static row size");
|
assert(c == Cols && "Mismatched between dynamic and static col size");
|
||||||
|
if constexpr (Cols == 1)
|
||||||
|
assert(r == Rows && "Mismatched between dynamic and static row size");
|
||||||
parent::conservativeResize(r, c);
|
parent::conservativeResize(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Constant(Scalar value) requires (Rows != -1 && Cols != -1)
|
static matrix Constant(Scalar value)
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Constant(Rows, Cols, static_cast<Scalar>(value));
|
return parent::Constant(Rows, Cols, static_cast<Scalar>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Constant(int rows, int cols, Scalar value)
|
static matrix Constant(int rows, int cols, Scalar value)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Constant(rows, cols, static_cast<Scalar>(value));
|
return parent::Constant(rows, cols, static_cast<Scalar>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Identity() requires (Rows != -1 && Cols != -1)
|
static matrix Identity()
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Identity(Rows, Cols);
|
return parent::Identity(Rows, Cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Identity(int rows, int cols)
|
static matrix Identity(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Identity(rows, cols);
|
return parent::Identity(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Ones() requires (Rows != -1 && Cols != -1)
|
static matrix Ones()
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Ones(Rows, Cols);
|
return parent::Ones(Rows, Cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Ones(int rows, int cols)
|
static matrix Ones(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Ones(rows, cols);
|
return parent::Ones(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Zero() requires (Rows != -1 && Cols != -1)
|
static matrix Zero()
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Zero(Rows, Cols);
|
return parent::Zero(Rows, Cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Zero(int rows, int cols)
|
static matrix Zero(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Zero(rows, cols);
|
return parent::Zero(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Random() requires (Rows != -1 && Cols != -1)
|
static matrix Random()
|
||||||
|
requires(Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
return parent::Random(Rows, Cols);
|
return parent::Random(Rows, Cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static matrix Random(int rows, int cols)
|
static matrix Random(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
assert(rows == Rows &&
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
|
if constexpr (Cols != -1)
|
||||||
|
assert(cols == Cols &&
|
||||||
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Random(rows, cols);
|
return parent::Random(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int P>
|
template<int P> value_type lpNorm() const
|
||||||
value_type lpNorm() const
|
|
||||||
{
|
{
|
||||||
static_assert(P == 1 || P == 2 || P == Infinity);
|
static_assert(P == 1 || P == 2 || P == Infinity);
|
||||||
return parent::template lpNorm<P>();
|
return parent::template lpNorm<P>();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator[](Index i) requires(IsVectorAtCompileTime)
|
value_type& operator[](Index i)
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return (*this)(i);
|
return (*this)(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type operator[](Index i) const requires(IsVectorAtCompileTime)
|
value_type operator[](Index i) const
|
||||||
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
return (*this)(i);
|
return (*this)(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
using parent::operator();
|
using parent::operator();
|
||||||
using parent::rows;
|
|
||||||
using parent::cols;
|
using parent::cols;
|
||||||
using parent::size;
|
|
||||||
using parent::prod;
|
|
||||||
using parent::mean;
|
|
||||||
using parent::trace;
|
|
||||||
using parent::squaredNorm;
|
|
||||||
using parent::norm;
|
|
||||||
using parent::sum;
|
|
||||||
using parent::data;
|
using parent::data;
|
||||||
|
using parent::mean;
|
||||||
|
using parent::norm;
|
||||||
|
using parent::prod;
|
||||||
|
using parent::rows;
|
||||||
|
using parent::size;
|
||||||
|
using parent::squaredNorm;
|
||||||
|
using parent::sum;
|
||||||
|
using parent::trace;
|
||||||
|
|
||||||
auto minCoeff() const { return parent::minCoeff(); }
|
auto minCoeff() const { return parent::minCoeff(); }
|
||||||
|
|
||||||
auto maxCoeff() const { return parent::maxCoeff(); }
|
auto maxCoeff() const { return parent::maxCoeff(); }
|
||||||
|
|
||||||
template<std::integral IndexType>
|
template<std::integral IndexType>
|
||||||
|
|
@ -432,10 +501,7 @@ namespace rotgen
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix operator-() const
|
matrix operator-() const { return matrix(base()(*this).operator-()); }
|
||||||
{
|
|
||||||
return matrix(base()(*this).operator-());
|
|
||||||
}
|
|
||||||
|
|
||||||
matrix& operator*=(matrix const& rhs)
|
matrix& operator*=(matrix const& rhs)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#if !defined(ROTGEN_FORCE_DYNAMIC)
|
#if !defined(ROTGEN_FORCE_DYNAMIC)
|
||||||
#include <Eigen/Dense>
|
#include <Eigen/Dense>
|
||||||
|
|
@ -36,72 +36,97 @@ namespace rotgen
|
||||||
using parent::noalias;
|
using parent::noalias;
|
||||||
using parent::operator();
|
using parent::operator();
|
||||||
using parent::operator[];
|
using parent::operator[];
|
||||||
using parent::rows;
|
|
||||||
using parent::cols;
|
using parent::cols;
|
||||||
using parent::size;
|
|
||||||
using parent::data;
|
|
||||||
using parent::sum;
|
|
||||||
using parent::prod;
|
|
||||||
using parent::mean;
|
|
||||||
using parent::trace;
|
|
||||||
using parent::transpose;
|
|
||||||
using parent::cwiseAbs;
|
using parent::cwiseAbs;
|
||||||
using parent::cwiseAbs2;
|
using parent::cwiseAbs2;
|
||||||
using parent::cwiseInverse;
|
using parent::cwiseInverse;
|
||||||
using parent::cwiseSqrt;
|
using parent::cwiseSqrt;
|
||||||
|
using parent::data;
|
||||||
|
using parent::lpNorm;
|
||||||
using parent::maxCoeff;
|
using parent::maxCoeff;
|
||||||
|
using parent::mean;
|
||||||
using parent::minCoeff;
|
using parent::minCoeff;
|
||||||
using parent::norm;
|
using parent::norm;
|
||||||
using parent::normalize;
|
using parent::normalize;
|
||||||
|
using parent::prod;
|
||||||
|
using parent::rows;
|
||||||
|
using parent::size;
|
||||||
using parent::squaredNorm;
|
using parent::squaredNorm;
|
||||||
using parent::lpNorm;
|
using parent::sum;
|
||||||
|
using parent::trace;
|
||||||
|
using parent::transpose;
|
||||||
using parent::operator+=;
|
using parent::operator+=;
|
||||||
using parent::operator-=;
|
using parent::operator-=;
|
||||||
using parent::operator*=;
|
using parent::operator*=;
|
||||||
using parent::operator/=;
|
using parent::operator/=;
|
||||||
using parent::Zero;
|
|
||||||
using parent::Constant;
|
using parent::Constant;
|
||||||
using parent::Random;
|
|
||||||
using parent::Identity;
|
using parent::Identity;
|
||||||
using parent::setZero;
|
|
||||||
using parent::setConstant;
|
|
||||||
using parent::setRandom;
|
|
||||||
using parent::setIdentity;
|
|
||||||
using parent::outerStride;
|
|
||||||
using parent::innerStride;
|
using parent::innerStride;
|
||||||
|
using parent::outerStride;
|
||||||
|
using parent::Random;
|
||||||
|
using parent::setConstant;
|
||||||
|
using parent::setIdentity;
|
||||||
|
using parent::setRandom;
|
||||||
|
using parent::setZero;
|
||||||
|
using parent::Zero;
|
||||||
|
|
||||||
using parent::operator=;
|
using parent::operator=;
|
||||||
|
|
||||||
using stride_type = typename parent::stride_type;
|
using stride_type = typename parent::stride_type;
|
||||||
|
|
||||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||||
|
|
||||||
parent& base() { return static_cast<parent&>(*this); }
|
parent& base() { return static_cast<parent&>(*this); }
|
||||||
|
|
||||||
template<std::same_as<value_type> S, int R, int C, int O, int MR, int MC>
|
template<std::same_as<value_type> S, int R, int C, int O, int MR, int MC>
|
||||||
ref(matrix<S, R, C, O, MR, MC>& m)
|
ref(matrix<S, R, C, O, MR, MC>& m)
|
||||||
: parent(m.data(), m.rows(), m.cols(), strides(m))
|
: parent(m.data(), m.rows(), m.cols(), strides(m))
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I>
|
template<typename Ref, int R, int C, bool I>
|
||||||
requires(std::same_as<value_type, typename Ref::value_type> && (Ref::storage_order & 1) == storage_order)
|
requires(std::same_as<value_type, typename Ref::value_type> &&
|
||||||
ref(block<Ref,R,C,I>&& b) : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
|
(Ref::storage_order & 1) == storage_order)
|
||||||
{}
|
ref(block<Ref, R, C, I>&& b)
|
||||||
|
: parent(b.data(),
|
||||||
|
b.rows(),
|
||||||
|
b.cols(),
|
||||||
|
stride_type{b.outerStride(), b.innerStride()})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I>
|
template<typename Ref, int R, int C, bool I>
|
||||||
requires(std::same_as<value_type, typename Ref::value_type> && (Ref::storage_order & 1) == storage_order)
|
requires(std::same_as<value_type, typename Ref::value_type> &&
|
||||||
ref(block<Ref,R,C,I>& b) : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
|
(Ref::storage_order & 1) == storage_order)
|
||||||
{}
|
ref(block<Ref, R, C, I>& b)
|
||||||
|
: parent(b.data(),
|
||||||
|
b.rows(),
|
||||||
|
b.cols(),
|
||||||
|
stride_type{b.outerStride(), b.innerStride()})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Ref, int O, typename S>
|
template<typename Ref, int O, typename S>
|
||||||
requires(std::same_as<value_type, typename Ref::value_type> && (Ref::storage_order & 1) == storage_order)
|
requires(std::same_as<value_type, typename Ref::value_type> &&
|
||||||
ref(map<Ref,O,S>& b) : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
|
(Ref::storage_order & 1) == storage_order)
|
||||||
{}
|
ref(map<Ref, O, S>& b)
|
||||||
|
: parent(b.data(),
|
||||||
|
b.rows(),
|
||||||
|
b.cols(),
|
||||||
|
stride_type{b.outerStride(), b.innerStride()})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename TT, int OO, typename SS>
|
template<typename TT, int OO, typename SS>
|
||||||
ref(ref<TT, OO, SS>& b)
|
ref(ref<TT, OO, SS>& b)
|
||||||
requires(std::same_as<value_type, typename TT::value_type> && (TT::storage_order & 1) == storage_order)
|
requires(std::same_as<value_type, typename TT::value_type> &&
|
||||||
: parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
|
(TT::storage_order & 1) == storage_order)
|
||||||
{}
|
: parent(b.data(),
|
||||||
|
b.rows(),
|
||||||
|
b.cols(),
|
||||||
|
stride_type{b.outerStride(), b.innerStride()})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ref(parent& m) : parent(m.data(), m.rows(), m.cols()) {}
|
ref(parent& m) : parent(m.data(), m.rows(), m.cols()) {}
|
||||||
|
|
||||||
|
|
@ -118,10 +143,10 @@ namespace rotgen
|
||||||
|
|
||||||
// Specialization for const matrix type
|
// Specialization for const matrix type
|
||||||
template<typename T, int Options, typename Stride>
|
template<typename T, int Options, typename Stride>
|
||||||
class ref<const T, Options,Stride> : private map<const T, Options,Stride>
|
class ref<T const, Options, Stride> : private map<T const, Options, Stride>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using parent = map<const T, Options,Stride>;
|
using parent = map<T const, Options, Stride>;
|
||||||
using value_type = typename T::value_type;
|
using value_type = typename T::value_type;
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
using rotgen_ref_tag = void;
|
using rotgen_ref_tag = void;
|
||||||
|
|
@ -136,35 +161,35 @@ namespace rotgen
|
||||||
using parent::noalias;
|
using parent::noalias;
|
||||||
using parent::operator();
|
using parent::operator();
|
||||||
using parent::operator[];
|
using parent::operator[];
|
||||||
using parent::rows;
|
|
||||||
using parent::cols;
|
using parent::cols;
|
||||||
using parent::size;
|
|
||||||
using parent::data;
|
|
||||||
using parent::sum;
|
|
||||||
using parent::prod;
|
|
||||||
using parent::mean;
|
|
||||||
using parent::trace;
|
|
||||||
using parent::transpose;
|
|
||||||
using parent::cwiseAbs;
|
using parent::cwiseAbs;
|
||||||
using parent::cwiseAbs2;
|
using parent::cwiseAbs2;
|
||||||
using parent::cwiseInverse;
|
using parent::cwiseInverse;
|
||||||
using parent::cwiseSqrt;
|
using parent::cwiseSqrt;
|
||||||
|
using parent::data;
|
||||||
|
using parent::lpNorm;
|
||||||
using parent::maxCoeff;
|
using parent::maxCoeff;
|
||||||
|
using parent::mean;
|
||||||
using parent::minCoeff;
|
using parent::minCoeff;
|
||||||
using parent::norm;
|
using parent::norm;
|
||||||
using parent::normalize;
|
using parent::normalize;
|
||||||
|
using parent::prod;
|
||||||
|
using parent::rows;
|
||||||
|
using parent::size;
|
||||||
using parent::squaredNorm;
|
using parent::squaredNorm;
|
||||||
using parent::lpNorm;
|
using parent::sum;
|
||||||
|
using parent::trace;
|
||||||
|
using parent::transpose;
|
||||||
using parent::operator+=;
|
using parent::operator+=;
|
||||||
using parent::operator-=;
|
using parent::operator-=;
|
||||||
using parent::operator*=;
|
using parent::operator*=;
|
||||||
using parent::operator/=;
|
using parent::operator/=;
|
||||||
using parent::Zero;
|
|
||||||
using parent::Constant;
|
using parent::Constant;
|
||||||
using parent::Random;
|
|
||||||
using parent::Identity;
|
using parent::Identity;
|
||||||
using parent::outerStride;
|
|
||||||
using parent::innerStride;
|
using parent::innerStride;
|
||||||
|
using parent::outerStride;
|
||||||
|
using parent::Random;
|
||||||
|
using parent::Zero;
|
||||||
|
|
||||||
using parent::operator=;
|
using parent::operator=;
|
||||||
|
|
||||||
|
|
@ -176,25 +201,41 @@ namespace rotgen
|
||||||
template<std::same_as<value_type> S, int R, int C, int O, int MR, int MC>
|
template<std::same_as<value_type> S, int R, int C, int O, int MR, int MC>
|
||||||
ref(matrix<S, R, C, O, MR, MC> const& m)
|
ref(matrix<S, R, C, O, MR, MC> const& m)
|
||||||
: parent(m.data(), m.rows(), m.cols(), strides(m))
|
: parent(m.data(), m.rows(), m.cols(), strides(m))
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I>
|
template<typename Ref, int R, int C, bool I>
|
||||||
ref(block<Ref, R, C, I> const& b)
|
ref(block<Ref, R, C, I> const& b)
|
||||||
requires(std::same_as<value_type, typename Ref::value_type> && (Ref::storage_order & 1) == storage_order)
|
requires(std::same_as<value_type, typename Ref::value_type> &&
|
||||||
: parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
|
(Ref::storage_order & 1) == storage_order)
|
||||||
{}
|
: parent(b.data(),
|
||||||
|
b.rows(),
|
||||||
|
b.cols(),
|
||||||
|
stride_type{b.outerStride(), b.innerStride()})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Ref, int O, typename S>
|
template<typename Ref, int O, typename S>
|
||||||
ref(map<Ref, O, S> const& b)
|
ref(map<Ref, O, S> const& b)
|
||||||
requires(std::same_as<value_type, typename Ref::value_type> && (Ref::storage_order & 1) == storage_order)
|
requires(std::same_as<value_type, typename Ref::value_type> &&
|
||||||
: parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
|
(Ref::storage_order & 1) == storage_order)
|
||||||
{}
|
: parent(b.data(),
|
||||||
|
b.rows(),
|
||||||
|
b.cols(),
|
||||||
|
stride_type{b.outerStride(), b.innerStride()})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<typename TT, int OO, typename SS>
|
template<typename TT, int OO, typename SS>
|
||||||
ref(ref<TT, OO, SS> const& b)
|
ref(ref<TT, OO, SS> const& b)
|
||||||
requires(std::same_as<value_type, typename TT::value_type> && (TT::storage_order & 1) == storage_order)
|
requires(std::same_as<value_type, typename TT::value_type> &&
|
||||||
: parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
|
(TT::storage_order & 1) == storage_order)
|
||||||
{}
|
: parent(b.data(),
|
||||||
|
b.rows(),
|
||||||
|
b.cols(),
|
||||||
|
stride_type{b.outerStride(), b.innerStride()})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ref(parent const& m) : parent(m.data(), m.rows(), m.cols()) {}
|
ref(parent const& m) : parent(m.data(), m.rows(), m.cols()) {}
|
||||||
|
|
||||||
|
|
@ -234,13 +275,15 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
auto operator+(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base() + rhs.base())
|
auto operator+(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||||
|
-> decltype(lhs.base() + rhs.base())
|
||||||
{
|
{
|
||||||
return lhs.base() + rhs.base();
|
return lhs.base() + rhs.base();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
auto operator+=(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base() += rhs.base())
|
auto operator+=(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||||
|
-> decltype(lhs.base() += rhs.base())
|
||||||
{
|
{
|
||||||
return lhs.base() += rhs.base();
|
return lhs.base() += rhs.base();
|
||||||
}
|
}
|
||||||
|
|
@ -252,7 +295,8 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
auto operator-=(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base() -= rhs.base())
|
auto operator-=(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||||
|
-> decltype(lhs.base() -= rhs.base())
|
||||||
{
|
{
|
||||||
return lhs.base() -= rhs.base();
|
return lhs.base() -= rhs.base();
|
||||||
}
|
}
|
||||||
|
|
@ -264,25 +308,29 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
auto operator*=(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base() *= rhs.base())
|
auto operator*=(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||||
|
-> decltype(lhs.base() *= rhs.base())
|
||||||
{
|
{
|
||||||
return lhs.base() *= rhs.base();
|
return lhs.base() *= rhs.base();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
template<typename A, int O, typename S>
|
||||||
auto operator*(ref<A,O,S> lhs, std::convertible_to<typename A::value_type> auto s)
|
auto operator*(ref<A, O, S> lhs,
|
||||||
|
std::convertible_to<typename A::value_type> auto s)
|
||||||
{
|
{
|
||||||
return lhs.base() * s;
|
return lhs.base() * s;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
template<typename A, int O, typename S>
|
||||||
auto operator*(std::convertible_to<typename A::value_type> auto s, ref<A,O,S> rhs)
|
auto operator*(std::convertible_to<typename A::value_type> auto s,
|
||||||
|
ref<A, O, S> rhs)
|
||||||
{
|
{
|
||||||
return s * rhs.base();
|
return s * rhs.base();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
template<typename A, int O, typename S>
|
||||||
auto operator/(ref<A,O,S> lhs, std::convertible_to<typename A::value_type> auto s)
|
auto operator/(ref<A, O, S> lhs,
|
||||||
|
std::convertible_to<typename A::value_type> auto s)
|
||||||
{
|
{
|
||||||
return lhs.base() / s;
|
return lhs.base() / s;
|
||||||
}
|
}
|
||||||
|
|
@ -294,67 +342,78 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
auto min(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base().cwiseMin(rhs.base()))
|
auto min(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||||
|
-> decltype(lhs.base().cwiseMin(rhs.base()))
|
||||||
{
|
{
|
||||||
return lhs.base().cwiseMin(rhs.base());
|
return lhs.base().cwiseMin(rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
template<typename A, int O, typename S>
|
||||||
auto min(ref<A,O,S> lhs, std::convertible_to<typename A::value_type> auto s) -> decltype(lhs.base().cwiseMin(s))
|
auto min(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||||
|
-> decltype(lhs.base().cwiseMin(s))
|
||||||
{
|
{
|
||||||
return lhs.base().cwiseMin(s);
|
return lhs.base().cwiseMin(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
template<typename A, int O, typename S>
|
||||||
auto min(std::convertible_to<typename A::value_type> auto s,ref<A,O,S> rhs) -> decltype(rhs.base().cwiseMin(s))
|
auto min(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
||||||
|
-> decltype(rhs.base().cwiseMin(s))
|
||||||
{
|
{
|
||||||
return rhs.base().cwiseMin(s);
|
return rhs.base().cwiseMin(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
auto max(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base().cwiseMax(rhs.base()))
|
auto max(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||||
|
-> decltype(lhs.base().cwiseMax(rhs.base()))
|
||||||
{
|
{
|
||||||
return lhs.base().cwiseMax(rhs.base());
|
return lhs.base().cwiseMax(rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
template<typename A, int O, typename S>
|
||||||
auto max(ref<A,O,S> lhs, std::convertible_to<typename A::value_type> auto s) -> decltype(lhs.base().cwiseMax(s))
|
auto max(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||||
|
-> decltype(lhs.base().cwiseMax(s))
|
||||||
{
|
{
|
||||||
return lhs.base().cwiseMax(s);
|
return lhs.base().cwiseMax(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
template<typename A, int O, typename S>
|
||||||
auto max(std::convertible_to<typename A::value_type> auto s,ref<A,O,S> rhs) -> decltype(rhs.base().cwiseMax(s))
|
auto max(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
||||||
|
-> decltype(rhs.base().cwiseMax(s))
|
||||||
{
|
{
|
||||||
return rhs.base().cwiseMax(s);
|
return rhs.base().cwiseMax(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
auto mul(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base().cwiseProduct(rhs.base()))
|
auto mul(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||||
|
-> decltype(lhs.base().cwiseProduct(rhs.base()))
|
||||||
{
|
{
|
||||||
return lhs.base().cwiseProduct(rhs.base());
|
return lhs.base().cwiseProduct(rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
template<typename A, int O, typename S>
|
||||||
auto mul(ref<A,O,S> lhs, std::convertible_to<typename A::value_type> auto s) -> decltype(lhs * s)
|
auto mul(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||||
|
-> decltype(lhs * s)
|
||||||
{
|
{
|
||||||
return lhs * s;
|
return lhs * s;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
template<typename A, int O, typename S>
|
||||||
auto mul(std::convertible_to<typename A::value_type> auto s,ref<A,O,S> rhs) -> decltype(s * rhs)
|
auto mul(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
||||||
|
-> decltype(s * rhs)
|
||||||
{
|
{
|
||||||
return s * rhs;
|
return s * rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
auto div(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base().cwiseQuotient(rhs.base()))
|
auto div(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||||
|
-> decltype(lhs.base().cwiseQuotient(rhs.base()))
|
||||||
{
|
{
|
||||||
return lhs.base().cwiseQuotient(rhs.base());
|
return lhs.base().cwiseQuotient(rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
template<typename A, int O, typename S>
|
||||||
auto div(ref<A,O,S> lhs, std::convertible_to<typename A::value_type> auto s) -> decltype(lhs / s)
|
auto div(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||||
|
-> decltype(lhs / s)
|
||||||
{
|
{
|
||||||
return lhs / s;
|
return lhs / s;
|
||||||
}
|
}
|
||||||
|
|
@ -366,13 +425,15 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
auto cross(ref<A,O,S> lhs, ref<B,P,T> rhs) -> decltype(lhs.base().cross(rhs.base()))
|
auto cross(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||||
|
-> decltype(lhs.base().cross(rhs.base()))
|
||||||
{
|
{
|
||||||
return lhs.base().cross(rhs.base());
|
return lhs.base().cross(rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------
|
||||||
// Convert entity/eigen types to a proper ref so we can write less function overloads
|
// Convert entity/eigen types to a proper ref so we can write less function
|
||||||
|
// overloads
|
||||||
template<typename T> struct generalize;
|
template<typename T> struct generalize;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
@ -382,42 +443,41 @@ namespace rotgen
|
||||||
using type = std::remove_cvref_t<T>;
|
using type = std::remove_cvref_t<T>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T> using generalize_t = typename generalize<T>::type;
|
||||||
using generalize_t = typename generalize<T>::type;
|
|
||||||
|
|
||||||
template<concepts::entity T> struct generalize<T>
|
template<concepts::entity T> struct generalize<T>
|
||||||
{
|
{
|
||||||
static constexpr bool is_const = std::is_const_v<T>;
|
static constexpr bool is_const = std::is_const_v<T>;
|
||||||
using base = matrix<typename T::value_type,T::RowsAtCompileTime,T::ColsAtCompileTime,T::storage_order>;
|
using base = matrix<typename T::value_type,
|
||||||
|
T::RowsAtCompileTime,
|
||||||
|
T::ColsAtCompileTime,
|
||||||
|
T::storage_order>;
|
||||||
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
|
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, int O, typename S>
|
template<typename T, int O, typename S> struct generalize<ref<T, O, S>>
|
||||||
struct generalize<ref<T,O,S>>
|
|
||||||
{
|
{
|
||||||
using type = ref<T, O, S>;
|
using type = ref<T, O, S>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, int O, typename S>
|
template<typename T, int O, typename S> struct generalize<ref<T, O, S> const>
|
||||||
struct generalize<ref<T,O,S> const>
|
|
||||||
{
|
{
|
||||||
using type = ref<T, O, S>;
|
using type = ref<T, O, S>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<concepts::entity T>
|
template<concepts::entity T> typename T::parent& base_of(T& a)
|
||||||
typename T::parent& base_of(T& a)
|
|
||||||
{
|
{
|
||||||
return a.base();
|
return a.base();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::entity T>
|
template<concepts::entity T> typename T::parent const& base_of(T const& a)
|
||||||
typename T::parent const& base_of(T const& a)
|
|
||||||
{
|
{
|
||||||
return a.base();
|
return a.base();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T base_of(T a) requires(std::is_arithmetic_v<T>)
|
T base_of(T a)
|
||||||
|
requires(std::is_arithmetic_v<T>)
|
||||||
{
|
{
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
@ -427,18 +487,19 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
static constexpr bool is_const = std::is_const_v<T>;
|
static constexpr bool is_const = std::is_const_v<T>;
|
||||||
using concrete_type = decltype(std::declval<T>().eval());
|
using concrete_type = decltype(std::declval<T>().eval());
|
||||||
using base = matrix<typename T::Scalar,T::RowsAtCompileTime,T::ColsAtCompileTime,concrete_type::Options&1>;
|
using base = matrix<typename T::Scalar,
|
||||||
|
T::RowsAtCompileTime,
|
||||||
|
T::ColsAtCompileTime,
|
||||||
|
concrete_type::Options & 1>;
|
||||||
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
|
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<concepts::eigen_compatible T>
|
template<concepts::eigen_compatible T> auto const& base_of(T const& a)
|
||||||
auto const& base_of(T const& a)
|
|
||||||
{
|
{
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::eigen_compatible T>
|
template<concepts::eigen_compatible T> auto& base_of(T& a)
|
||||||
auto& base_of(T& a)
|
|
||||||
{
|
{
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,11 @@ namespace rotgen
|
||||||
static constexpr bool is_dynamic = true;
|
static constexpr bool is_dynamic = true;
|
||||||
|
|
||||||
stride() : outer_(-1), inner_(1) {}
|
stride() : outer_(-1), inner_(1) {}
|
||||||
|
|
||||||
stride(Index s, Index i) : outer_(s), inner_(i) {}
|
stride(Index s, Index i) : outer_(s), inner_(i) {}
|
||||||
|
|
||||||
Index inner() const { return inner_; }
|
Index inner() const { return inner_; }
|
||||||
|
|
||||||
Index outer() const { return outer_; }
|
Index outer() const { return outer_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -34,34 +36,34 @@ namespace rotgen
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<Index Value= Dynamic>
|
template<Index Value = Dynamic> struct inner_stride : stride
|
||||||
struct inner_stride : stride
|
|
||||||
{
|
{
|
||||||
static constexpr bool is_dynamic = Value == Dynamic;
|
static constexpr bool is_dynamic = Value == Dynamic;
|
||||||
|
|
||||||
inner_stride() : stride(-1, Value) {}
|
inner_stride() : stride(-1, Value) {}
|
||||||
|
|
||||||
inner_stride(Index v) : stride(0, v) {}
|
inner_stride(Index v) : stride(0, v) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<Index Value = Dynamic>
|
template<Index Value = Dynamic> struct outer_stride : stride
|
||||||
struct outer_stride : stride
|
|
||||||
{
|
{
|
||||||
static constexpr bool is_dynamic = Value == Dynamic;
|
static constexpr bool is_dynamic = Value == Dynamic;
|
||||||
|
|
||||||
outer_stride() : stride(Value, 0) {}
|
outer_stride() : stride(Value, 0) {}
|
||||||
|
|
||||||
outer_stride(Index v) : stride(v, 0) {}
|
outer_stride(Index v) : stride(v, 0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
inner_stride(Index) -> inner_stride<Dynamic>;
|
inner_stride(Index) -> inner_stride<Dynamic>;
|
||||||
outer_stride(Index) -> outer_stride<Dynamic>;
|
outer_stride(Index) -> outer_stride<Dynamic>;
|
||||||
|
|
||||||
template<int Order>
|
template<int Order> stride strides(Index r, Index c)
|
||||||
stride strides(Index r, Index c)
|
|
||||||
{
|
{
|
||||||
if constexpr (Order == RowMajor) return {c, 1};
|
if constexpr (Order == RowMajor) return {c, 1};
|
||||||
else return {r, 1};
|
else return {r, 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int Order>
|
template<int Order> stride strides(stride const& original, Index, Index)
|
||||||
stride strides(stride const& original,Index, Index)
|
|
||||||
{
|
{
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
@ -73,8 +75,7 @@ namespace rotgen
|
||||||
else return {original.outer(), 1};
|
else return {original.outer(), 1};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::entity E>
|
template<concepts::entity E> auto strides(E const& e)
|
||||||
auto strides(const E& e)
|
|
||||||
{
|
{
|
||||||
return strides<E::storage_order>(e.rows(), e.cols());
|
return strides<E::storage_order>(e.rows(), e.cols());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,4 +37,3 @@
|
||||||
#ifndef ROTGEN_DEPRECATED_NO_EXPORT
|
#ifndef ROTGEN_DEPRECATED_NO_EXPORT
|
||||||
#define ROTGEN_DEPRECATED_NO_EXPORT ROTGEN_NO_EXPORT ROTGEN_DEPRECATED
|
#define ROTGEN_DEPRECATED_NO_EXPORT ROTGEN_NO_EXPORT ROTGEN_DEPRECATED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,5 @@
|
||||||
|
|
||||||
#define ROTGEN_CAT(a, ...) ROTGEN_PRIMITIVE_CAT(a, __VA_ARGS__)
|
#define ROTGEN_CAT(a, ...) ROTGEN_PRIMITIVE_CAT(a, __VA_ARGS__)
|
||||||
#define ROTGEN_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
|
#define ROTGEN_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
|
||||||
#define ROTGEN_MATRIX_NAME(BASE,ID,SUFFIX) ROTGEN_CAT(BASE,ROTGEN_CAT(ID,SUFFIX))
|
#define ROTGEN_MATRIX_NAME(BASE, ID, SUFFIX) \
|
||||||
|
ROTGEN_CAT(BASE, ROTGEN_CAT(ID, SUFFIX))
|
||||||
|
|
|
||||||
|
|
@ -9,50 +9,55 @@
|
||||||
|
|
||||||
namespace rotgen::detail
|
namespace rotgen::detail
|
||||||
{
|
{
|
||||||
template< typename EigenType
|
template<typename EigenType,
|
||||||
, template<typename,int,int,int,int,int> typename Wrapper
|
template<typename, int, int, int, int, int> typename Wrapper>
|
||||||
>
|
|
||||||
struct as_concrete
|
struct as_concrete
|
||||||
{
|
{
|
||||||
using type = Wrapper< typename EigenType::value_type
|
using type = Wrapper<typename EigenType::value_type,
|
||||||
, EigenType::RowsAtCompileTime, EigenType::ColsAtCompileTime
|
EigenType::RowsAtCompileTime,
|
||||||
, EigenType::Flags & 1
|
EigenType::ColsAtCompileTime,
|
||||||
, EigenType::MaxRowsAtCompileTime, EigenType::MaxColsAtCompileTime
|
EigenType::Flags & 1,
|
||||||
>;
|
EigenType::MaxRowsAtCompileTime,
|
||||||
|
EigenType::MaxColsAtCompileTime>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename EigenType
|
template<typename EigenType,
|
||||||
, template<typename,int,int,int,int,int> typename Wrapper
|
template<typename, int, int, int, int, int> typename Wrapper>
|
||||||
>
|
using as_concrete_t =
|
||||||
using as_concrete_t = typename as_concrete<std::remove_cvref_t<EigenType>,Wrapper>::type;
|
typename as_concrete<std::remove_cvref_t<EigenType>, Wrapper>::type;
|
||||||
|
|
||||||
template<typename M, typename N>
|
template<typename M, typename N>
|
||||||
inline constexpr bool has_same_vector_size = []()
|
inline constexpr bool has_same_vector_size = []() {
|
||||||
{
|
|
||||||
// No vector = noo size
|
// No vector = noo size
|
||||||
if (!(M::IsVectorAtCompileTime && N::IsVectorAtCompileTime)) return false;
|
if (!(M::IsVectorAtCompileTime && N::IsVectorAtCompileTime)) return false;
|
||||||
// Row vectors -> same Cols
|
// Row vectors -> same Cols
|
||||||
if(M::RowsAtCompileTime == 1 && N::RowsAtCompileTime == 1) return M::ColsAtCompileTime == N::ColsAtCompileTime;
|
if (M::RowsAtCompileTime == 1 && N::RowsAtCompileTime == 1)
|
||||||
|
return M::ColsAtCompileTime == N::ColsAtCompileTime;
|
||||||
// Col vectors -> same Rows
|
// Col vectors -> same Rows
|
||||||
if(M::ColsAtCompileTime == 1 && N::ColsAtCompileTime == 1) return M::RowsAtCompileTime == N::RowsAtCompileTime;
|
if (M::ColsAtCompileTime == 1 && N::ColsAtCompileTime == 1)
|
||||||
|
return M::RowsAtCompileTime == N::RowsAtCompileTime;
|
||||||
// Mixing 1xN with Mx1
|
// Mixing 1xN with Mx1
|
||||||
return false;
|
return false;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using propagate_const = std::conditional_t<T::is_immutable || std::is_const_v<T>, std::add_const_t<T>, T>;
|
using propagate_const =
|
||||||
|
std::conditional_t<T::is_immutable || std::is_const_v<T>,
|
||||||
|
std::add_const_t<T>,
|
||||||
|
T>;
|
||||||
|
|
||||||
template<auto M, auto N>
|
template<auto M, auto N>
|
||||||
inline constexpr auto select_static = (M==rotgen::Dynamic || N==rotgen::Dynamic) ? rotgen::Dynamic : M;
|
inline constexpr auto select_static =
|
||||||
|
(M == rotgen::Dynamic || N == rotgen::Dynamic) ? rotgen::Dynamic : M;
|
||||||
|
|
||||||
template< typename M1, typename M2
|
template<typename M1,
|
||||||
, template<typename,int,int,int,int,int> typename Wrapper
|
typename M2,
|
||||||
>
|
template<typename, int, int, int, int, int> typename Wrapper>
|
||||||
using composite_type = Wrapper< typename M1::value_type
|
using composite_type =
|
||||||
, select_static<M1::RowsAtCompileTime,M2::RowsAtCompileTime>
|
Wrapper<typename M1::value_type,
|
||||||
, select_static<M1::ColsAtCompileTime,M2::ColsAtCompileTime>
|
select_static<M1::RowsAtCompileTime, M2::RowsAtCompileTime>,
|
||||||
, M1::storage_order
|
select_static<M1::ColsAtCompileTime, M2::ColsAtCompileTime>,
|
||||||
, select_static<M1::MaxRowsAtCompileTime,M2::MaxRowsAtCompileTime>
|
M1::storage_order,
|
||||||
, select_static<M1::MaxColsAtCompileTime,M2::MaxColsAtCompileTime>
|
select_static<M1::MaxRowsAtCompileTime, M2::MaxRowsAtCompileTime>,
|
||||||
>;
|
select_static<M1::MaxColsAtCompileTime, M2::MaxColsAtCompileTime>>;
|
||||||
}
|
}
|
||||||
|
|
@ -21,166 +21,246 @@ namespace rotgen
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
struct matrix_impl64_col::payload
|
struct matrix_impl64_col::payload
|
||||||
{
|
{
|
||||||
using data_type = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>;
|
using data_type =
|
||||||
|
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
|
||||||
payload(std::size_t r = 0, std::size_t c = 0) : data(r, c) {}
|
payload(std::size_t r = 0, std::size_t c = 0) : data(r, c) {}
|
||||||
payload(std::initializer_list<std::initializer_list<double>> init) : data(init) {}
|
|
||||||
|
payload(std::initializer_list<std::initializer_list<double>> init)
|
||||||
|
: data(init)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
||||||
|
|
||||||
void assign(Eigen::Block<data_type> ref) { data = ref; }
|
void assign(Eigen::Block<data_type> ref) { data = ref; }
|
||||||
|
|
||||||
void assign(data_type const& mat) { data = mat; }
|
void assign(data_type const& mat) { data = mat; }
|
||||||
|
|
||||||
void assign(data_type&& mat) { data = std::move(mat); }
|
void assign(data_type&& mat) { data = std::move(mat); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct matrix_impl64_row::payload
|
struct matrix_impl64_row::payload
|
||||||
{
|
{
|
||||||
using data_type = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
|
using data_type =
|
||||||
|
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
|
||||||
payload(std::size_t r = 0, std::size_t c = 0) : data(r, c) {}
|
payload(std::size_t r = 0, std::size_t c = 0) : data(r, c) {}
|
||||||
payload(std::initializer_list<std::initializer_list<double>> init) : data(init) {}
|
|
||||||
|
payload(std::initializer_list<std::initializer_list<double>> init)
|
||||||
|
: data(init)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
||||||
|
|
||||||
void assign(Eigen::Block<data_type> ref) { data = ref; }
|
void assign(Eigen::Block<data_type> ref) { data = ref; }
|
||||||
|
|
||||||
void assign(data_type const& mat) { data = mat; }
|
void assign(data_type const& mat) { data = mat; }
|
||||||
|
|
||||||
void assign(data_type&& mat) { data = std::move(mat); }
|
void assign(data_type&& mat) { data = std::move(mat); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct matrix_impl32_col::payload
|
struct matrix_impl32_col::payload
|
||||||
{
|
{
|
||||||
using data_type = Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>;
|
using data_type =
|
||||||
|
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
|
||||||
payload(std::size_t r = 0, std::size_t c = 0) : data(r, c) {}
|
payload(std::size_t r = 0, std::size_t c = 0) : data(r, c) {}
|
||||||
payload(std::initializer_list<std::initializer_list<float>> init) : data(init) {}
|
|
||||||
|
payload(std::initializer_list<std::initializer_list<float>> init)
|
||||||
|
: data(init)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
||||||
|
|
||||||
void assign(Eigen::Block<data_type> ref) { data = ref; }
|
void assign(Eigen::Block<data_type> ref) { data = ref; }
|
||||||
|
|
||||||
void assign(data_type const& mat) { data = mat; }
|
void assign(data_type const& mat) { data = mat; }
|
||||||
|
|
||||||
void assign(data_type&& mat) { data = std::move(mat); }
|
void assign(data_type&& mat) { data = std::move(mat); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct matrix_impl32_row::payload
|
struct matrix_impl32_row::payload
|
||||||
{
|
{
|
||||||
using data_type = Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
|
using data_type =
|
||||||
|
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
|
||||||
payload(std::size_t r = 0, std::size_t c = 0) : data(r, c) {}
|
payload(std::size_t r = 0, std::size_t c = 0) : data(r, c) {}
|
||||||
payload(std::initializer_list<std::initializer_list<float>> init) : data(init) {}
|
|
||||||
|
payload(std::initializer_list<std::initializer_list<float>> init)
|
||||||
|
: data(init)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
||||||
|
|
||||||
void assign(Eigen::Block<data_type> ref) { data = ref; }
|
void assign(Eigen::Block<data_type> ref) { data = ref; }
|
||||||
|
|
||||||
void assign(data_type const& mat) { data = mat; }
|
void assign(data_type const& mat) { data = mat; }
|
||||||
|
|
||||||
void assign(data_type&& mat) { data = std::move(mat); }
|
void assign(data_type&& mat) { data = std::move(mat); }
|
||||||
};
|
};
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Internal payload - Required for cross-referencing from mixed order on map operators
|
// Internal payload - Required for cross-referencing from mixed order on map
|
||||||
|
// operators
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
struct map_const_impl32_col::payload
|
struct map_const_impl32_col::payload
|
||||||
{
|
{
|
||||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
using base_type = Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>;
|
using base_type =
|
||||||
using data_type = Eigen::Map<base_type const,Eigen::Unaligned,stride_type>;
|
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||||
|
using data_type =
|
||||||
|
Eigen::Map<base_type const, Eigen::Unaligned, stride_type>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
|
||||||
payload(data_type const& o) : data(o) {}
|
payload(data_type const& o) : data(o) {}
|
||||||
|
|
||||||
payload(float const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
payload(float const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||||
payload (float const* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
|
|
||||||
|
payload(float const* ptr, Index r, Index c, stride_type s)
|
||||||
|
: data(ptr, r, c, s)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct map_const_impl32_row::payload
|
struct map_const_impl32_row::payload
|
||||||
{
|
{
|
||||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
using base_type = Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
|
using base_type =
|
||||||
using data_type = Eigen::Map<base_type const,Eigen::Unaligned,stride_type>;
|
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||||
|
using data_type =
|
||||||
|
Eigen::Map<base_type const, Eigen::Unaligned, stride_type>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
|
||||||
payload(data_type const& o) : data(o) {}
|
payload(data_type const& o) : data(o) {}
|
||||||
|
|
||||||
payload(float const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
payload(float const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||||
payload (float const* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
|
|
||||||
|
payload(float const* ptr, Index r, Index c, stride_type s)
|
||||||
|
: data(ptr, r, c, s)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct map_impl32_col::payload
|
struct map_impl32_col::payload
|
||||||
{
|
{
|
||||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
using base_type = Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>;
|
using base_type =
|
||||||
|
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||||
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
|
||||||
payload(data_type const& o) : data(o) {}
|
payload(data_type const& o) : data(o) {}
|
||||||
|
|
||||||
payload(float* ptr, Index r, Index c) : data(ptr, r, c) {}
|
payload(float* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||||
|
|
||||||
payload(float* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s) {}
|
payload(float* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct map_impl32_row::payload
|
struct map_impl32_row::payload
|
||||||
{
|
{
|
||||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
using base_type = Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
|
using base_type =
|
||||||
|
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||||
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
|
||||||
payload(data_type const& o) : data(o) {}
|
payload(data_type const& o) : data(o) {}
|
||||||
|
|
||||||
payload(float* ptr, Index r, Index c) : data(ptr, r, c) {}
|
payload(float* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||||
|
|
||||||
payload(float* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s) {}
|
payload(float* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct map_const_impl64_col::payload
|
struct map_const_impl64_col::payload
|
||||||
{
|
{
|
||||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
using base_type = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>;
|
using base_type =
|
||||||
using data_type = Eigen::Map<base_type const,Eigen::Unaligned,stride_type>;
|
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||||
|
using data_type =
|
||||||
|
Eigen::Map<base_type const, Eigen::Unaligned, stride_type>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
|
||||||
payload(data_type const& o) : data(o) {}
|
payload(data_type const& o) : data(o) {}
|
||||||
|
|
||||||
payload(double const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
payload(double const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||||
payload (double const* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
|
|
||||||
|
payload(double const* ptr, Index r, Index c, stride_type s)
|
||||||
|
: data(ptr, r, c, s)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct map_const_impl64_row::payload
|
struct map_const_impl64_row::payload
|
||||||
{
|
{
|
||||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
using base_type = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
|
using base_type =
|
||||||
using data_type = Eigen::Map<base_type const,Eigen::Unaligned,stride_type>;
|
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||||
|
using data_type =
|
||||||
|
Eigen::Map<base_type const, Eigen::Unaligned, stride_type>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
|
||||||
payload(data_type const& o) : data(o) {}
|
payload(data_type const& o) : data(o) {}
|
||||||
|
|
||||||
payload(double const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
payload(double const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||||
payload (double const* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
|
|
||||||
|
payload(double const* ptr, Index r, Index c, stride_type s)
|
||||||
|
: data(ptr, r, c, s)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct map_impl64_col::payload
|
struct map_impl64_col::payload
|
||||||
{
|
{
|
||||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
using base_type = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>;
|
using base_type =
|
||||||
|
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||||
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
|
||||||
payload(data_type const& o) : data(o) {}
|
payload(data_type const& o) : data(o) {}
|
||||||
|
|
||||||
payload(double* ptr, Index r, Index c) : data(ptr, r, c) {}
|
payload(double* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||||
payload (double* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
|
|
||||||
|
payload(double* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct map_impl64_row::payload
|
struct map_impl64_row::payload
|
||||||
{
|
{
|
||||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
using base_type = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
|
using base_type =
|
||||||
|
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||||
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
|
||||||
payload(data_type const& o) : data(o) {}
|
payload(data_type const& o) : data(o) {}
|
||||||
|
|
||||||
payload(double* ptr, Index r, Index c) : data(ptr, r, c) {}
|
payload(double* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||||
payload (double* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
|
|
||||||
|
payload(double* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -188,13 +268,17 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
Eigen::IOFormat instance;
|
Eigen::IOFormat instance;
|
||||||
|
|
||||||
payload ( int p, int f
|
payload(int p,
|
||||||
, std::string const& cs, std::string const& rsp
|
int f,
|
||||||
, std::string const& rp, std::string const& rs
|
std::string const& cs,
|
||||||
, std::string const& mp, std::string const& ms
|
std::string const& rsp,
|
||||||
, char fill
|
std::string const& rp,
|
||||||
)
|
std::string const& rs,
|
||||||
|
std::string const& mp,
|
||||||
|
std::string const& ms,
|
||||||
|
char fill)
|
||||||
: instance(p, f, cs, rsp, rp, rs, mp, ms, fill)
|
: instance(p, f, cs, rsp, rp, rs, mp, ms, fill)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -20,31 +20,31 @@ namespace rotgen
|
||||||
std::unique_ptr<payload> storage_;
|
std::unique_ptr<payload> storage_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ioformat( int precision, int flags = 0
|
ioformat(int precision,
|
||||||
, std::string const& coeffSeparator = " "
|
int flags = 0,
|
||||||
, std::string const& rowSeparator = "\n"
|
std::string const& coeffSeparator = " ",
|
||||||
, std::string const& rowPrefix = "", std::string const& rowSuffix = ""
|
std::string const& rowSeparator = "\n",
|
||||||
, std::string const& matPrefix = "", std::string const& matSuffix = ""
|
std::string const& rowPrefix = "",
|
||||||
, char fill = ' '
|
std::string const& rowSuffix = "",
|
||||||
);
|
std::string const& matPrefix = "",
|
||||||
|
std::string const& matSuffix = "",
|
||||||
|
char fill = ' ');
|
||||||
|
|
||||||
~ioformat();
|
~ioformat();
|
||||||
|
|
||||||
std::unique_ptr<payload> const& storage() const { return storage_; }
|
std::unique_ptr<payload> const& storage() const { return storage_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename M>
|
template<typename M> struct format
|
||||||
struct format
|
|
||||||
{
|
{
|
||||||
format(const M& m, const ioformat& f) : matrix_(m), format_(f) {}
|
format(M const& m, ioformat const& f) : matrix_(m), format_(f) {}
|
||||||
|
|
||||||
M const& matrix_;
|
M const& matrix_;
|
||||||
ioformat const& format_;
|
ioformat const& format_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename M>
|
template<typename M>
|
||||||
std::ostream& operator<<(std::ostream& os, const format<M>& f)
|
std::ostream& operator<<(std::ostream& os, format<M> const& f)
|
||||||
{
|
{
|
||||||
return os << format{f.matrix_.base(), f.format_};
|
return os << format{f.matrix_.base(), f.format_};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,19 +17,19 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
using ioformat = Eigen::IOFormat;
|
using ioformat = Eigen::IOFormat;
|
||||||
|
|
||||||
template <typename M>
|
template<typename M> struct format
|
||||||
struct format
|
|
||||||
{
|
{
|
||||||
format(const M& m, const ioformat& f) : matrix_(m), format_(f) {}
|
format(M const& m, ioformat const& f) : matrix_(m), format_(f) {}
|
||||||
|
|
||||||
M const& matrix_;
|
M const& matrix_;
|
||||||
ioformat const& format_;
|
ioformat const& format_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename M>
|
template<typename M>
|
||||||
std::ostream& operator<<(std::ostream& os, const format<M>& f)
|
std::ostream& operator<<(std::ostream& os, format<M> const& f)
|
||||||
{
|
{
|
||||||
if constexpr(concepts::eigen_compatible<M>) return os << f.matrix_.format(f.format_);
|
if constexpr (concepts::eigen_compatible<M>)
|
||||||
|
return os << f.matrix_.format(f.format_);
|
||||||
else return os << f.matrix_.base().format(f.format_);
|
else return os << f.matrix_.base().format(f.format_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,11 @@ namespace rotgen
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<concepts::entity Entity>
|
template<concepts::entity Entity>
|
||||||
void validate_extract ( [[maybe_unused]] Entity& e
|
void validate_extract([[maybe_unused]] Entity& e,
|
||||||
, [[maybe_unused]] Index i0, [[maybe_unused]] Index j0
|
[[maybe_unused]] Index i0,
|
||||||
, [[maybe_unused]] Index ni, [[maybe_unused]] Index nj
|
[[maybe_unused]] Index j0,
|
||||||
)
|
[[maybe_unused]] Index ni,
|
||||||
|
[[maybe_unused]] Index nj)
|
||||||
{
|
{
|
||||||
assert(i0 >= 0 && "block extraction uses negative row index.");
|
assert(i0 >= 0 && "block extraction uses negative row index.");
|
||||||
assert(j0 >= 0 && "block extraction uses negative col index.");
|
assert(j0 >= 0 && "block extraction uses negative col index.");
|
||||||
|
|
@ -24,6 +25,7 @@ namespace rotgen
|
||||||
assert(j0 + nj <= e.cols() && "block extraction cols is out of range.");
|
assert(j0 + nj <= e.cols() && "block extraction cols is out of range.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================== EXTRACT ========================
|
//======================== EXTRACT ========================
|
||||||
template<concepts::entity Entity>
|
template<concepts::entity Entity>
|
||||||
auto extract(Entity& e, Index i0, Index j0, Index ni, Index nj)
|
auto extract(Entity& e, Index i0, Index j0, Index ni, Index nj)
|
||||||
|
|
@ -31,8 +33,7 @@ namespace rotgen
|
||||||
detail::validate_extract(e, i0, j0, ni, nj);
|
detail::validate_extract(e, i0, j0, ni, nj);
|
||||||
if constexpr (concepts::reference<Entity>)
|
if constexpr (concepts::reference<Entity>)
|
||||||
return extract(e.base(), i0, j0, ni, nj);
|
return extract(e.base(), i0, j0, ni, nj);
|
||||||
else
|
else return block<detail::propagate_const<Entity>>(e, i0, j0, ni, nj);
|
||||||
return block<detail::propagate_const<Entity>>(e, i0, j0, ni, nj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Index NI, Index NJ, concepts::entity Entity>
|
template<Index NI, Index NJ, concepts::entity Entity>
|
||||||
|
|
@ -42,8 +43,7 @@ namespace rotgen
|
||||||
detail::validate_extract(e, i0, j0, NI, NJ);
|
detail::validate_extract(e, i0, j0, NI, NJ);
|
||||||
if constexpr (concepts::reference<Entity>)
|
if constexpr (concepts::reference<Entity>)
|
||||||
return extract<NI, NJ>(e.base(), i0, j0);
|
return extract<NI, NJ>(e.base(), i0, j0);
|
||||||
else
|
else return block<detail::propagate_const<Entity>, NI, NJ>(e, i0, j0);
|
||||||
return block<detail::propagate_const<Entity> ,NI,NJ>(e, i0, j0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Index NI, Index NJ, concepts::entity Entity>
|
template<Index NI, Index NJ, concepts::entity Entity>
|
||||||
|
|
@ -110,14 +110,12 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================== TOP ROWS ========================
|
//======================== TOP ROWS ========================
|
||||||
template<concepts::entity Entity>
|
template<concepts::entity Entity> auto topRows(Entity& e, Index ni)
|
||||||
auto topRows(Entity& e, Index ni)
|
|
||||||
{
|
{
|
||||||
return extract(e, 0, 0, ni, e.cols());
|
return extract(e, 0, 0, ni, e.cols());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Index NI, concepts::entity Entity>
|
template<Index NI, concepts::entity Entity> auto topRows(Entity& e)
|
||||||
auto topRows(Entity& e)
|
|
||||||
{
|
{
|
||||||
return extract<NI, -1>(e, 0, 0, NI, e.cols());
|
return extract<NI, -1>(e, 0, 0, NI, e.cols());
|
||||||
}
|
}
|
||||||
|
|
@ -136,27 +134,23 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================== BOTTOM ROWS ========================
|
//======================== BOTTOM ROWS ========================
|
||||||
template<concepts::entity Entity>
|
template<concepts::entity Entity> auto bottomRows(Entity& e, Index ni)
|
||||||
auto bottomRows(Entity& e, Index ni)
|
|
||||||
{
|
{
|
||||||
return extract(e, e.rows() - ni, 0, ni, e.cols());
|
return extract(e, e.rows() - ni, 0, ni, e.cols());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Index NI, concepts::entity Entity>
|
template<Index NI, concepts::entity Entity> auto bottomRows(Entity& e)
|
||||||
auto bottomRows(Entity& e)
|
|
||||||
{
|
{
|
||||||
return extract<NI, -1>(e, e.rows() - NI, 0, NI, e.cols());
|
return extract<NI, -1>(e, e.rows() - NI, 0, NI, e.cols());
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================== LEFT COLS ========================
|
//======================== LEFT COLS ========================
|
||||||
template<concepts::entity Entity>
|
template<concepts::entity Entity> auto leftCols(Entity& e, Index nj)
|
||||||
auto leftCols(Entity& e, Index nj)
|
|
||||||
{
|
{
|
||||||
return extract(e, 0, 0, e.rows(), nj);
|
return extract(e, 0, 0, e.rows(), nj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Index NJ, concepts::entity Entity>
|
template<Index NJ, concepts::entity Entity> auto leftCols(Entity& e)
|
||||||
auto leftCols(Entity& e)
|
|
||||||
{
|
{
|
||||||
return extract<-1, NJ>(e, 0, 0, e.rows(), NJ);
|
return extract<-1, NJ>(e, 0, 0, e.rows(), NJ);
|
||||||
}
|
}
|
||||||
|
|
@ -175,28 +169,24 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================== RIGHT COLS ========================
|
//======================== RIGHT COLS ========================
|
||||||
template<concepts::entity Entity>
|
template<concepts::entity Entity> auto rightCols(Entity& e, Index nj)
|
||||||
auto rightCols(Entity& e, Index nj)
|
|
||||||
{
|
{
|
||||||
return extract(e, 0, e.cols() - nj, e.rows(), nj);
|
return extract(e, 0, e.cols() - nj, e.rows(), nj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Index NJ, concepts::entity Entity>
|
template<Index NJ, concepts::entity Entity> auto rightCols(Entity& e)
|
||||||
auto rightCols(Entity& e)
|
|
||||||
{
|
{
|
||||||
return extract<-1, NJ>(e, 0, e.cols() - NJ, e.rows(), NJ);
|
return extract<-1, NJ>(e, 0, e.cols() - NJ, e.rows(), NJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================== ROW ========================
|
//======================== ROW ========================
|
||||||
template<concepts::entity Entity>
|
template<concepts::entity Entity> auto row(Entity& e, Index i0)
|
||||||
auto row(Entity& e, Index i0)
|
|
||||||
{
|
{
|
||||||
return extract<1, -1>(e, i0, 0, 1, e.cols());
|
return extract<1, -1>(e, i0, 0, 1, e.cols());
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================== COL ========================
|
//======================== COL ========================
|
||||||
template<concepts::entity Entity>
|
template<concepts::entity Entity> auto col(Entity& e, Index j0)
|
||||||
auto col(Entity& e, Index j0)
|
|
||||||
{
|
{
|
||||||
return extract<-1, 1>(e, 0, j0, e.rows(), 1);
|
return extract<-1, 1>(e, 0, j0, e.rows(), 1);
|
||||||
}
|
}
|
||||||
|
|
@ -206,15 +196,19 @@ namespace rotgen
|
||||||
auto head(Entity& e, Index n)
|
auto head(Entity& e, Index n)
|
||||||
requires(Entity::RowsAtCompileTime == 1 || Entity::ColsAtCompileTime == 1)
|
requires(Entity::RowsAtCompileTime == 1 || Entity::ColsAtCompileTime == 1)
|
||||||
{
|
{
|
||||||
if constexpr(Entity::RowsAtCompileTime==1) return extract<1,Dynamic>(e,0,0,1,n);
|
if constexpr (Entity::RowsAtCompileTime == 1)
|
||||||
else if constexpr(Entity::ColsAtCompileTime==1) return extract<Dynamic,1>(e,0,0,n,1);
|
return extract<1, Dynamic>(e, 0, 0, 1, n);
|
||||||
|
else if constexpr (Entity::ColsAtCompileTime == 1)
|
||||||
|
return extract<Dynamic, 1>(e, 0, 0, n, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Index N, concepts::entity Entity>
|
template<Index N, concepts::entity Entity>
|
||||||
auto head(Entity& e) requires(Entity::RowsAtCompileTime==1 || Entity::ColsAtCompileTime==1)
|
auto head(Entity& e)
|
||||||
|
requires(Entity::RowsAtCompileTime == 1 || Entity::ColsAtCompileTime == 1)
|
||||||
{
|
{
|
||||||
if constexpr (Entity::RowsAtCompileTime == 1) return extract<1, N>(e, 0, 0);
|
if constexpr (Entity::RowsAtCompileTime == 1) return extract<1, N>(e, 0, 0);
|
||||||
else if constexpr(Entity::ColsAtCompileTime==1) return extract<N,1>(e,0,0);
|
else if constexpr (Entity::ColsAtCompileTime == 1)
|
||||||
|
return extract<N, 1>(e, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================== VECTOR TAIL ========================
|
//======================== VECTOR TAIL ========================
|
||||||
|
|
@ -222,15 +216,20 @@ namespace rotgen
|
||||||
auto tail(Entity& e, Index n)
|
auto tail(Entity& e, Index n)
|
||||||
requires(Entity::RowsAtCompileTime == 1 || Entity::ColsAtCompileTime == 1)
|
requires(Entity::RowsAtCompileTime == 1 || Entity::ColsAtCompileTime == 1)
|
||||||
{
|
{
|
||||||
if constexpr(Entity::RowsAtCompileTime==1) return extract<1,Dynamic>(e,0,e.cols()-n,1,n);
|
if constexpr (Entity::RowsAtCompileTime == 1)
|
||||||
else if constexpr(Entity::ColsAtCompileTime==1) return extract<Dynamic,1>(e,e.rows()-n,0,n,1);
|
return extract<1, Dynamic>(e, 0, e.cols() - n, 1, n);
|
||||||
|
else if constexpr (Entity::ColsAtCompileTime == 1)
|
||||||
|
return extract<Dynamic, 1>(e, e.rows() - n, 0, n, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Index N, concepts::entity Entity>
|
template<Index N, concepts::entity Entity>
|
||||||
auto tail(Entity& e) requires(Entity::RowsAtCompileTime==1 || Entity::ColsAtCompileTime==1)
|
auto tail(Entity& e)
|
||||||
|
requires(Entity::RowsAtCompileTime == 1 || Entity::ColsAtCompileTime == 1)
|
||||||
{
|
{
|
||||||
if constexpr(Entity::RowsAtCompileTime==1) return extract<1,N>(e,0,e.cols()-N);
|
if constexpr (Entity::RowsAtCompileTime == 1)
|
||||||
else if constexpr(Entity::ColsAtCompileTime==1) return extract<N,1>(e,e.rows()-N,0);
|
return extract<1, N>(e, 0, e.cols() - N);
|
||||||
|
else if constexpr (Entity::ColsAtCompileTime == 1)
|
||||||
|
return extract<N, 1>(e, e.rows() - N, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================== VECTOR SEGMENT ========================
|
//======================== VECTOR SEGMENT ========================
|
||||||
|
|
@ -238,14 +237,18 @@ namespace rotgen
|
||||||
auto segment(Entity& e, Index s, Index n)
|
auto segment(Entity& e, Index s, Index n)
|
||||||
requires(Entity::RowsAtCompileTime == 1 || Entity::ColsAtCompileTime == 1)
|
requires(Entity::RowsAtCompileTime == 1 || Entity::ColsAtCompileTime == 1)
|
||||||
{
|
{
|
||||||
if constexpr(Entity::RowsAtCompileTime==1) return extract<1,Dynamic>(e,0,s,1,n);
|
if constexpr (Entity::RowsAtCompileTime == 1)
|
||||||
else if constexpr(Entity::ColsAtCompileTime==1) return extract<Dynamic,1>(e,s,0,n,1);
|
return extract<1, Dynamic>(e, 0, s, 1, n);
|
||||||
|
else if constexpr (Entity::ColsAtCompileTime == 1)
|
||||||
|
return extract<Dynamic, 1>(e, s, 0, n, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Index N, concepts::entity Entity>
|
template<Index N, concepts::entity Entity>
|
||||||
auto segment(Entity& e, Index s) requires(Entity::RowsAtCompileTime==1 || Entity::ColsAtCompileTime==1)
|
auto segment(Entity& e, Index s)
|
||||||
|
requires(Entity::RowsAtCompileTime == 1 || Entity::ColsAtCompileTime == 1)
|
||||||
{
|
{
|
||||||
if constexpr (Entity::RowsAtCompileTime == 1) return extract<1, N>(e, 0, s);
|
if constexpr (Entity::RowsAtCompileTime == 1) return extract<1, N>(e, 0, s);
|
||||||
else if constexpr(Entity::ColsAtCompileTime==1) return extract<N,1>(e,s,0);
|
else if constexpr (Entity::ColsAtCompileTime == 1)
|
||||||
|
return extract<N, 1>(e, s, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,19 +14,44 @@ namespace rotgen
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
// Infos & Shape
|
// Infos & Shape
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
std::size_t rows(auto const& m) requires(requires{ m.rows(); }){ return m.rows(); }
|
std::size_t rows(auto const& m)
|
||||||
std::size_t cols(auto const& m) requires(requires{ m.cols(); }){ return m.cols(); }
|
requires(requires { m.rows(); })
|
||||||
std::size_t size(auto const& m) requires(requires{ m.size(); }){ return m.size(); }
|
{
|
||||||
|
return m.rows();
|
||||||
|
}
|
||||||
|
|
||||||
void resize(auto& a, int s) requires requires{a.resize(s);} { a.resize(s); }
|
std::size_t cols(auto const& m)
|
||||||
void resize(auto& a, int r, int c) requires requires{a.resize(r,c);} { a.resize(r,c); }
|
requires(requires { m.cols(); })
|
||||||
|
{
|
||||||
|
return m.cols();
|
||||||
|
}
|
||||||
|
|
||||||
void conservativeResize(auto& a, int s) requires requires{a.conservativeResize(s);}
|
std::size_t size(auto const& m)
|
||||||
|
requires(requires { m.size(); })
|
||||||
|
{
|
||||||
|
return m.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void resize(auto& a, int s)
|
||||||
|
requires requires { a.resize(s); }
|
||||||
|
{
|
||||||
|
a.resize(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resize(auto& a, int r, int c)
|
||||||
|
requires requires { a.resize(r, c); }
|
||||||
|
{
|
||||||
|
a.resize(r, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void conservativeResize(auto& a, int s)
|
||||||
|
requires requires { a.conservativeResize(s); }
|
||||||
{
|
{
|
||||||
a.conservativeResize(s);
|
a.conservativeResize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void conservativeResize(auto& a, int r, int c) requires requires{a.conservativeResize(r,c);}
|
void conservativeResize(auto& a, int r, int c)
|
||||||
|
requires requires { a.conservativeResize(r, c); }
|
||||||
{
|
{
|
||||||
a.conservativeResize(r, c);
|
a.conservativeResize(r, c);
|
||||||
}
|
}
|
||||||
|
|
@ -34,69 +59,128 @@ namespace rotgen
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
// Global operations
|
// Global operations
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
decltype(auto) normalized (auto const& m) requires(requires{ m.normalized(); }) { return m.normalized(); }
|
decltype(auto) normalized(auto const& m)
|
||||||
decltype(auto) transpose (auto const& m) requires(requires{ m.transpose(); }) { return m.transpose(); }
|
requires(requires { m.normalized(); })
|
||||||
decltype(auto) conjugate (auto const& m) requires(requires{ m.conjugate(); }) { return m.conjugate(); }
|
{
|
||||||
decltype(auto) adjoint (auto const& m) requires(requires{ m.adjoint(); }) { return m.adjoint(); }
|
return m.normalized();
|
||||||
|
}
|
||||||
|
|
||||||
void normalize(auto& a) requires(requires{ a.normalize(); }) { a.normalize(); }
|
decltype(auto) transpose(auto const& m)
|
||||||
void transposeInPlace(auto& a) requires(requires{ a.transposeInPlace(); }) { a.transposeInPlace(); }
|
requires(requires { m.transpose(); })
|
||||||
void adjointInPlace(auto& a) requires(requires{ a.adjointInPlace(); }) { a.adjointInPlace(); }
|
{
|
||||||
|
return m.transpose();
|
||||||
|
}
|
||||||
|
|
||||||
|
decltype(auto) conjugate(auto const& m)
|
||||||
|
requires(requires { m.conjugate(); })
|
||||||
|
{
|
||||||
|
return m.conjugate();
|
||||||
|
}
|
||||||
|
|
||||||
|
decltype(auto) adjoint(auto const& m)
|
||||||
|
requires(requires { m.adjoint(); })
|
||||||
|
{
|
||||||
|
return m.adjoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void normalize(auto& a)
|
||||||
|
requires(requires { a.normalize(); })
|
||||||
|
{
|
||||||
|
a.normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void transposeInPlace(auto& a)
|
||||||
|
requires(requires { a.transposeInPlace(); })
|
||||||
|
{
|
||||||
|
a.transposeInPlace();
|
||||||
|
}
|
||||||
|
|
||||||
|
void adjointInPlace(auto& a)
|
||||||
|
requires(requires { a.adjointInPlace(); })
|
||||||
|
{
|
||||||
|
a.adjointInPlace();
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
// Component-wise functions
|
// Component-wise functions
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
auto abs (auto const& arg) requires(requires{arg.cwiseAbs();} ) { return arg.cwiseAbs(); }
|
auto abs(auto const& arg)
|
||||||
auto abs2(auto const& arg) requires(requires{arg.cwiseAbs2();} ) { return arg.cwiseAbs2(); }
|
requires(requires { arg.cwiseAbs(); })
|
||||||
auto rec (auto const& arg) requires(requires{arg.cwiseInverse();}) { return arg.cwiseInverse(); }
|
{
|
||||||
auto sqrt(auto const& arg) requires(requires{arg.cwiseSqrt();} ) { return arg.cwiseSqrt(); }
|
return arg.cwiseAbs();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto abs2(auto const& arg)
|
||||||
|
requires(requires { arg.cwiseAbs2(); })
|
||||||
|
{
|
||||||
|
return arg.cwiseAbs2();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rec(auto const& arg)
|
||||||
|
requires(requires { arg.cwiseInverse(); })
|
||||||
|
{
|
||||||
|
return arg.cwiseInverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto sqrt(auto const& arg)
|
||||||
|
requires(requires { arg.cwiseSqrt(); })
|
||||||
|
{
|
||||||
|
return arg.cwiseSqrt();
|
||||||
|
}
|
||||||
|
|
||||||
template<concepts::entity A, concepts::entity B>
|
template<concepts::entity A, concepts::entity B>
|
||||||
auto min(A const& a, B const& b)
|
auto min(A const& a, B const& b)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return min(generalize_t<A const>(a), generalize_t<B const>(b));
|
if constexpr (!use_expression_templates)
|
||||||
|
return min(generalize_t<A const>(a), generalize_t<B const>(b));
|
||||||
else return base_of(a).cwiseMin(base_of(b));
|
else return base_of(a).cwiseMin(base_of(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::entity A>
|
template<concepts::entity A>
|
||||||
auto min(A const& a, std::convertible_to<typename A::value_type> auto b)
|
auto min(A const& a, std::convertible_to<typename A::value_type> auto b)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return min(generalize_t<A const>(a), b);
|
if constexpr (!use_expression_templates)
|
||||||
|
return min(generalize_t<A const>(a), b);
|
||||||
else return base_of(a).cwiseMin(b);
|
else return base_of(a).cwiseMin(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::entity B>
|
template<concepts::entity B>
|
||||||
auto min(std::convertible_to<typename B::value_type> auto a, B const& b)
|
auto min(std::convertible_to<typename B::value_type> auto a, B const& b)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return min(a,generalize_t<B const>(b));
|
if constexpr (!use_expression_templates)
|
||||||
|
return min(a, generalize_t<B const>(b));
|
||||||
else return base_of(b).cwiseMin(a);
|
else return base_of(b).cwiseMin(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::entity A, concepts::entity B>
|
template<concepts::entity A, concepts::entity B>
|
||||||
auto max(A const& a, B const& b)
|
auto max(A const& a, B const& b)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return max(generalize_t<A const>(a), generalize_t<B const>(b));
|
if constexpr (!use_expression_templates)
|
||||||
|
return max(generalize_t<A const>(a), generalize_t<B const>(b));
|
||||||
else return base_of(a).cwiseMax(base_of(b));
|
else return base_of(a).cwiseMax(base_of(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::entity A>
|
template<concepts::entity A>
|
||||||
auto max(A const& a, std::convertible_to<typename A::value_type> auto b)
|
auto max(A const& a, std::convertible_to<typename A::value_type> auto b)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return max(generalize_t<A const>(a), b);
|
if constexpr (!use_expression_templates)
|
||||||
|
return max(generalize_t<A const>(a), b);
|
||||||
else return base_of(a).cwiseMax(b);
|
else return base_of(a).cwiseMax(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::entity B>
|
template<concepts::entity B>
|
||||||
auto max(std::convertible_to<typename B::value_type> auto a, B const& b)
|
auto max(std::convertible_to<typename B::value_type> auto a, B const& b)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return max(a, generalize_t<B const>(b));
|
if constexpr (!use_expression_templates)
|
||||||
|
return max(a, generalize_t<B const>(b));
|
||||||
else return base_of(b).cwiseMax(a);
|
else return base_of(b).cwiseMax(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::entity A, concepts::entity B>
|
template<concepts::entity A, concepts::entity B>
|
||||||
auto mul(A const& a, B const& b)
|
auto mul(A const& a, B const& b)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return mul(generalize_t<A const>(a), generalize_t<B const>(b));
|
if constexpr (!use_expression_templates)
|
||||||
|
return mul(generalize_t<A const>(a), generalize_t<B const>(b));
|
||||||
else return base_of(a).cwiseProduct(base_of(b));
|
else return base_of(a).cwiseProduct(base_of(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,7 +199,8 @@ namespace rotgen
|
||||||
template<concepts::entity A, concepts::entity B>
|
template<concepts::entity A, concepts::entity B>
|
||||||
auto div(A const& a, B const& b)
|
auto div(A const& a, B const& b)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return div(generalize_t<A const>(a), generalize_t<B const>(b));
|
if constexpr (!use_expression_templates)
|
||||||
|
return div(generalize_t<A const>(a), generalize_t<B const>(b));
|
||||||
else return base_of(a).array() / base_of(b).array();
|
else return base_of(a).array() / base_of(b).array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -125,8 +210,7 @@ namespace rotgen
|
||||||
return a / b;
|
return a / b;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::entity A>
|
template<concepts::entity A> auto square(A const& a)
|
||||||
auto square(A const& a)
|
|
||||||
{
|
{
|
||||||
return mul(a, a);
|
return mul(a, a);
|
||||||
}
|
}
|
||||||
|
|
@ -134,38 +218,78 @@ namespace rotgen
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
// Reductions
|
// Reductions
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
auto trace(concepts::entity auto const& arg) { return arg.trace(); }
|
auto trace(concepts::entity auto const& arg)
|
||||||
auto squaredNorm(concepts::entity auto const& arg) { return arg.squaredNorm(); }
|
{
|
||||||
auto norm(concepts::entity auto const& arg) { return arg.norm(); }
|
return arg.trace();
|
||||||
auto sum(auto const& arg) requires requires{ arg.sum(); } { return arg.sum(); }
|
}
|
||||||
auto prod(concepts::entity auto const& arg) { return arg.prod(); }
|
|
||||||
auto mean(concepts::entity auto const& arg) { return arg.mean(); }
|
auto squaredNorm(concepts::entity auto const& arg)
|
||||||
|
{
|
||||||
|
return arg.squaredNorm();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto norm(concepts::entity auto const& arg)
|
||||||
|
{
|
||||||
|
return arg.norm();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto sum(auto const& arg)
|
||||||
|
requires requires { arg.sum(); }
|
||||||
|
{
|
||||||
|
return arg.sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto prod(concepts::entity auto const& arg)
|
||||||
|
{
|
||||||
|
return arg.prod();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mean(concepts::entity auto const& arg)
|
||||||
|
{
|
||||||
|
return arg.mean();
|
||||||
|
}
|
||||||
|
|
||||||
template<concepts::entity A, concepts::entity B>
|
template<concepts::entity A, concepts::entity B>
|
||||||
auto dot(A const& a, B const& b)
|
auto dot(A const& a, B const& b)
|
||||||
requires(detail::has_same_vector_size<A,B> && std::same_as<typename A::value_type, typename B::value_type>)
|
requires(detail::has_same_vector_size<A, B> &&
|
||||||
|
std::same_as<typename A::value_type, typename B::value_type>)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return dot(generalize_t<A const>(a), generalize_t<B const>(b));
|
if constexpr (!use_expression_templates)
|
||||||
|
return dot(generalize_t<A const>(a), generalize_t<B const>(b));
|
||||||
else return base_of(a).dot(base_of(b));
|
else return base_of(a).dot(base_of(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto maxCoeff(auto const& arg) requires( requires{ arg.maxCoeff(); } ) { return arg.maxCoeff(); }
|
auto maxCoeff(auto const& arg)
|
||||||
auto minCoeff(auto const& arg) requires( requires{ arg.minCoeff(); } ) { return arg.minCoeff(); }
|
requires(requires { arg.maxCoeff(); })
|
||||||
|
{
|
||||||
|
return arg.maxCoeff();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto minCoeff(auto const& arg)
|
||||||
|
requires(requires { arg.minCoeff(); })
|
||||||
|
{
|
||||||
|
return arg.minCoeff();
|
||||||
|
}
|
||||||
|
|
||||||
template<std::integral IndexType>
|
template<std::integral IndexType>
|
||||||
auto maxCoeff(concepts::entity auto const& arg, IndexType* row, IndexType* col)
|
auto maxCoeff(concepts::entity auto const& arg,
|
||||||
|
IndexType* row,
|
||||||
|
IndexType* col)
|
||||||
{
|
{
|
||||||
return arg.maxCoeff(row, col);
|
return arg.maxCoeff(row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::integral IndexType>
|
template<std::integral IndexType>
|
||||||
auto minCoeff(concepts::entity auto const& arg, IndexType* row, IndexType* col)
|
auto minCoeff(concepts::entity auto const& arg,
|
||||||
|
IndexType* row,
|
||||||
|
IndexType* col)
|
||||||
{
|
{
|
||||||
return arg.minCoeff(row, col);
|
return arg.minCoeff(row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int P, typename T>
|
template<int P, typename T>
|
||||||
auto lpNorm(T const& arg) requires( requires{arg.template lpNorm<P>();} )
|
auto lpNorm(T const& arg)
|
||||||
|
requires(requires { arg.template lpNorm<P>(); })
|
||||||
{
|
{
|
||||||
static_assert(P == 1 || P == 2 || P == Infinity);
|
static_assert(P == 1 || P == 2 || P == Infinity);
|
||||||
return arg.template lpNorm<P>();
|
return arg.template lpNorm<P>();
|
||||||
|
|
@ -175,19 +299,22 @@ namespace rotgen
|
||||||
// Expression handling
|
// Expression handling
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
template<typename T>
|
template<typename T>
|
||||||
decltype(auto) noalias(T&& t) requires( requires{std::forward<T>(t).noalias();} )
|
decltype(auto) noalias(T&& t)
|
||||||
|
requires(requires { std::forward<T>(t).noalias(); })
|
||||||
{
|
{
|
||||||
return std::forward<T>(t).noalias();
|
return std::forward<T>(t).noalias();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto evaluate(T&& t) requires( requires{std::forward<T>(t).evaluate();} )
|
auto evaluate(T&& t)
|
||||||
|
requires(requires { std::forward<T>(t).evaluate(); })
|
||||||
{
|
{
|
||||||
return std::forward<T>(t).evaluate();
|
return std::forward<T>(t).evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto evaluate(T&& t) requires( requires{std::forward<T>(t).eval();} )
|
auto evaluate(T&& t)
|
||||||
|
requires(requires { std::forward<T>(t).eval(); })
|
||||||
{
|
{
|
||||||
return std::forward<T>(t).eval();
|
return std::forward<T>(t).eval();
|
||||||
}
|
}
|
||||||
|
|
@ -196,141 +323,167 @@ namespace rotgen
|
||||||
// Generators
|
// Generators
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setZero(T&& t) requires( requires{std::forward<T>(t).setZero();} )
|
auto setZero(T&& t)
|
||||||
|
requires(requires { std::forward<T>(t).setZero(); })
|
||||||
{
|
{
|
||||||
return std::forward<T>(t).setZero();
|
return std::forward<T>(t).setZero();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setZero() requires( requires{T::Zero();} )
|
auto setZero()
|
||||||
|
requires(requires { T::Zero(); })
|
||||||
{
|
{
|
||||||
return T::Zero();
|
return T::Zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setZero(std::integral auto n) requires( requires{T::Zero(n);} )
|
auto setZero(std::integral auto n)
|
||||||
|
requires(requires { T::Zero(n); })
|
||||||
{
|
{
|
||||||
return T::Zero(n);
|
return T::Zero(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setZero(std::integral auto r,std::integral auto c) requires( requires{T::Zero(r,c);} )
|
auto setZero(std::integral auto r, std::integral auto c)
|
||||||
|
requires(requires { T::Zero(r, c); })
|
||||||
{
|
{
|
||||||
return T::Zero(r, c);
|
return T::Zero(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setOnes(T&& t) requires( requires{std::forward<T>(t).setOnes();} )
|
auto setOnes(T&& t)
|
||||||
|
requires(requires { std::forward<T>(t).setOnes(); })
|
||||||
{
|
{
|
||||||
return std::forward<T>(t).setOnes();
|
return std::forward<T>(t).setOnes();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setOnes() requires( requires{T::Ones();} )
|
auto setOnes()
|
||||||
|
requires(requires { T::Ones(); })
|
||||||
{
|
{
|
||||||
return T::Ones();
|
return T::Ones();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setOnes(std::integral auto n) requires( requires{T::Ones(n);} )
|
auto setOnes(std::integral auto n)
|
||||||
|
requires(requires { T::Ones(n); })
|
||||||
{
|
{
|
||||||
return T::Ones(n);
|
return T::Ones(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setOnes(std::integral auto r,std::integral auto c) requires( requires{T::Ones(r,c);} )
|
auto setOnes(std::integral auto r, std::integral auto c)
|
||||||
|
requires(requires { T::Ones(r, c); })
|
||||||
{
|
{
|
||||||
return T::Ones(r, c);
|
return T::Ones(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setIdentity(T&& t) requires( requires{std::forward<T>(t).setIdentity();} )
|
auto setIdentity(T&& t)
|
||||||
|
requires(requires { std::forward<T>(t).setIdentity(); })
|
||||||
{
|
{
|
||||||
return std::forward<T>(t).setIdentity();
|
return std::forward<T>(t).setIdentity();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setIdentity() requires( requires{T::Identity();} )
|
auto setIdentity()
|
||||||
|
requires(requires { T::Identity(); })
|
||||||
{
|
{
|
||||||
return T::Identity();
|
return T::Identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setIdentity(std::integral auto n) requires( requires{T::Identity(n);} )
|
auto setIdentity(std::integral auto n)
|
||||||
|
requires(requires { T::Identity(n); })
|
||||||
{
|
{
|
||||||
return T::Identity(n);
|
return T::Identity(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setIdentity(std::integral auto r,std::integral auto c) requires( requires{T::Identity(r,c);} )
|
auto setIdentity(std::integral auto r, std::integral auto c)
|
||||||
|
requires(requires { T::Identity(r, c); })
|
||||||
{
|
{
|
||||||
return T::Identity(r, c);
|
return T::Identity(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setRandom(T&& t) requires( requires{std::forward<T>(t).setRandom();} )
|
auto setRandom(T&& t)
|
||||||
|
requires(requires { std::forward<T>(t).setRandom(); })
|
||||||
{
|
{
|
||||||
return std::forward<T>(t).setRandom();
|
return std::forward<T>(t).setRandom();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setRandom() requires( requires{T::Random();} )
|
auto setRandom()
|
||||||
|
requires(requires { T::Random(); })
|
||||||
{
|
{
|
||||||
return T::Random();
|
return T::Random();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setRandom(std::integral auto n) requires( requires{T::Random(n);} )
|
auto setRandom(std::integral auto n)
|
||||||
|
requires(requires { T::Random(n); })
|
||||||
{
|
{
|
||||||
return T::Random(n);
|
return T::Random(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setRandom(std::integral auto r,std::integral auto c) requires( requires{T::Random(r,c);} )
|
auto setRandom(std::integral auto r, std::integral auto c)
|
||||||
|
requires(requires { T::Random(r, c); })
|
||||||
{
|
{
|
||||||
return T::Random(r, c);
|
return T::Random(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setConstant(T&& t, auto v) requires( requires{std::forward<T>(t).setConstant(v);} )
|
auto setConstant(T&& t, auto v)
|
||||||
|
requires(requires { std::forward<T>(t).setConstant(v); })
|
||||||
{
|
{
|
||||||
return std::forward<T>(t).setConstant(v);
|
return std::forward<T>(t).setConstant(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setConstant(auto v) requires( requires{T::Constant(v);} )
|
auto setConstant(auto v)
|
||||||
|
requires(requires { T::Constant(v); })
|
||||||
{
|
{
|
||||||
return T::Constant(v);
|
return T::Constant(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setConstant(std::integral auto n, auto v) requires( requires{T::Constant(n,v);} )
|
auto setConstant(std::integral auto n, auto v)
|
||||||
|
requires(requires { T::Constant(n, v); })
|
||||||
{
|
{
|
||||||
return T::Constant(n, v);
|
return T::Constant(n, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
auto setConstant(std::integral auto r,std::integral auto c, auto v) requires( requires{T::Constant(r,c,v);} )
|
auto setConstant(std::integral auto r, std::integral auto c, auto v)
|
||||||
|
requires(requires { T::Constant(r, c, v); })
|
||||||
{
|
{
|
||||||
return T::Constant(r, c, v);
|
return T::Constant(r, c, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
// Others
|
// Others
|
||||||
// TODO: Adapt other functions ot behave as inverse and limit code in non-ref/non-map containers
|
// TODO: Adapt other functions ot behave as inverse and limit code in
|
||||||
|
// non-ref/non-map containers
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
template<typename A> auto inverse(A const& a)
|
template<typename A> auto inverse(A const& a)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return inverse(generalize_t<A const>(a));
|
if constexpr (!use_expression_templates)
|
||||||
else if constexpr(requires{typename A::rotgen_tag;}) return base_of(a).inverse();
|
return inverse(generalize_t<A const>(a));
|
||||||
|
else if constexpr (requires { typename A::rotgen_tag; })
|
||||||
|
return base_of(a).inverse();
|
||||||
else return a.inverse();
|
else return a.inverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::vectorND<3> L, concepts::vectorND<3> R> auto cross(L const& l, R const& r)
|
template<concepts::vectorND<3> L, concepts::vectorND<3> R>
|
||||||
|
auto cross(L const& l, R const& r)
|
||||||
{
|
{
|
||||||
if constexpr (!use_expression_templates)
|
if constexpr (!use_expression_templates)
|
||||||
return cross(generalize_t<R const>(l), generalize_t<R const>(r));
|
return cross(generalize_t<R const>(l), generalize_t<R const>(r));
|
||||||
else if constexpr(requires{typename L::rotgen_tag;} || requires{typename R::rotgen_tag;} )
|
else if constexpr (
|
||||||
|
requires { typename L::rotgen_tag; } ||
|
||||||
|
requires { typename R::rotgen_tag; })
|
||||||
return base_of(l).cross(base_of(r));
|
return base_of(l).cross(base_of(r));
|
||||||
else return l.cross(r);
|
else return l.cross(r);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,10 @@ namespace rotgen
|
||||||
constexpr bool operator==(A const& a, B const& b) noexcept
|
constexpr bool operator==(A const& a, B const& b) noexcept
|
||||||
requires(concepts::entity<A> || concepts::entity<B>)
|
requires(concepts::entity<A> || concepts::entity<B>)
|
||||||
{
|
{
|
||||||
static_assert ( std::same_as<typename A::value_type,typename B::value_type>
|
static_assert(std::same_as<typename A::value_type, typename B::value_type>,
|
||||||
, "[ROTGEN] Incompatible type in operator=="
|
"[ROTGEN] Incompatible type in operator==");
|
||||||
);
|
if constexpr (!use_expression_templates)
|
||||||
if constexpr(!use_expression_templates) return generalize_t<A const>(a) == generalize_t<B const>(b);
|
return generalize_t<A const>(a) == generalize_t<B const>(b);
|
||||||
else return base_of(a) == base_of(b);
|
else return base_of(a) == base_of(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,38 +34,46 @@ namespace rotgen
|
||||||
constexpr bool operator!=(A const& a, B const& b) noexcept
|
constexpr bool operator!=(A const& a, B const& b) noexcept
|
||||||
requires(concepts::entity<A> || concepts::entity<B>)
|
requires(concepts::entity<A> || concepts::entity<B>)
|
||||||
{
|
{
|
||||||
static_assert ( std::same_as<typename A::value_type,typename B::value_type>
|
static_assert(std::same_as<typename A::value_type, typename B::value_type>,
|
||||||
, "[ROTGEN] Incompatible type in operator!="
|
"[ROTGEN] Incompatible type in operator!=");
|
||||||
);
|
if constexpr (!use_expression_templates)
|
||||||
if constexpr(!use_expression_templates) return generalize_t<A const>(a) != generalize_t<B const>(b);
|
return generalize_t<A const>(a) != generalize_t<B const>(b);
|
||||||
else return base_of(a) != base_of(b);
|
else return base_of(a) != base_of(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
auto operator+(A const& a, B const& b) requires(concepts::entity<A> || concepts::entity<B>)
|
auto operator+(A const& a, B const& b)
|
||||||
|
requires(concepts::entity<A> || concepts::entity<B>)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return generalize_t<A const>(a) + generalize_t<B const>(b);
|
if constexpr (!use_expression_templates)
|
||||||
|
return generalize_t<A const>(a) + generalize_t<B const>(b);
|
||||||
else return base_of(a) + base_of(b);
|
else return base_of(a) + base_of(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
auto operator-(A const& a, B const& b) requires(concepts::entity<A> || concepts::entity<B>)
|
auto operator-(A const& a, B const& b)
|
||||||
|
requires(concepts::entity<A> || concepts::entity<B>)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return generalize_t<A const>(a) - generalize_t<B const>(b);
|
if constexpr (!use_expression_templates)
|
||||||
|
return generalize_t<A const>(a) - generalize_t<B const>(b);
|
||||||
else return base_of(a) - base_of(b);
|
else return base_of(a) - base_of(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
auto operator*(A const& a, B const& b) requires(concepts::entity<A> || concepts::entity<B>)
|
auto operator*(A const& a, B const& b)
|
||||||
|
requires(concepts::entity<A> || concepts::entity<B>)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return generalize_t<A const>(a) * generalize_t<B const>(b);
|
if constexpr (!use_expression_templates)
|
||||||
|
return generalize_t<A const>(a) * generalize_t<B const>(b);
|
||||||
else return base_of(a) * base_of(b);
|
else return base_of(a) * base_of(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
auto operator/(A const& a, B const& b) requires(concepts::entity<A> && std::is_arithmetic_v<B>)
|
auto operator/(A const& a, B const& b)
|
||||||
|
requires(concepts::entity<A> && std::is_arithmetic_v<B>)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return generalize_t<A const>(a) / b;
|
if constexpr (!use_expression_templates)
|
||||||
|
return generalize_t<A const>(a) / b;
|
||||||
else return base_of(a) / b;
|
else return base_of(a) / b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,7 +83,8 @@ namespace rotgen
|
||||||
auto operator+=(A& a, B const& b)
|
auto operator+=(A& a, B const& b)
|
||||||
requires(concepts::entity<A> || concepts::entity<B>)
|
requires(concepts::entity<A> || concepts::entity<B>)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return generalize_t<A>(a) += generalize_t<B const>(b);
|
if constexpr (!use_expression_templates)
|
||||||
|
return generalize_t<A>(a) += generalize_t<B const>(b);
|
||||||
else return base_of(a) += base_of(b);
|
else return base_of(a) += base_of(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,7 +92,8 @@ namespace rotgen
|
||||||
auto operator-=(A& a, B const& b)
|
auto operator-=(A& a, B const& b)
|
||||||
requires(concepts::entity<A> || concepts::entity<B>)
|
requires(concepts::entity<A> || concepts::entity<B>)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return generalize_t<A>(a) -= generalize_t<B const>(b);
|
if constexpr (!use_expression_templates)
|
||||||
|
return generalize_t<A>(a) -= generalize_t<B const>(b);
|
||||||
else return base_of(a) -= base_of(b);
|
else return base_of(a) -= base_of(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,7 +101,8 @@ namespace rotgen
|
||||||
auto operator*=(A& a, B const& b)
|
auto operator*=(A& a, B const& b)
|
||||||
requires(concepts::entity<A> || concepts::entity<B>)
|
requires(concepts::entity<A> || concepts::entity<B>)
|
||||||
{
|
{
|
||||||
if constexpr(!use_expression_templates) return generalize_t<A>(a) *= generalize_t<B const>(b);
|
if constexpr (!use_expression_templates)
|
||||||
|
return generalize_t<A>(a) *= generalize_t<B const>(b);
|
||||||
else return base_of(a) *= base_of(b);
|
else return base_of(a) *= base_of(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -66,14 +66,12 @@ namespace rotgen
|
||||||
private:
|
private:
|
||||||
template<typename Func> void apply(Func f)
|
template<typename Func> void apply(Func f)
|
||||||
{
|
{
|
||||||
for(Index i = 0; i < target_.rows(); ++i)
|
for (Index i = 0; i < target_.rows(); ++i) f(row(target_, i), i);
|
||||||
f(row(target_,i), i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Func> void apply(Func f) const
|
template<typename Func> void apply(Func f) const
|
||||||
{
|
{
|
||||||
for(Index i = 0; i < target_.rows(); ++i)
|
for (Index i = 0; i < target_.rows(); ++i) f(row(target_, i), i);
|
||||||
f(row(target_,i), i);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -134,14 +132,12 @@ namespace rotgen
|
||||||
private:
|
private:
|
||||||
template<typename Func> void apply(Func f)
|
template<typename Func> void apply(Func f)
|
||||||
{
|
{
|
||||||
for(Index i = 0; i < target_.cols(); ++i)
|
for (Index i = 0; i < target_.cols(); ++i) f(col(target_, i), i);
|
||||||
f(col(target_,i), i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Func> void apply(Func f) const
|
template<typename Func> void apply(Func f) const
|
||||||
{
|
{
|
||||||
for(Index i = 0; i < target_.cols(); ++i)
|
for (Index i = 0; i < target_.cols(); ++i) f(col(target_, i), i);
|
||||||
f(col(target_,i), i);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,11 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
//clang-format off
|
||||||
#include <rotgen/config.hpp>
|
#include <rotgen/config.hpp>
|
||||||
#include <rotgen/format.hpp>
|
#include <rotgen/format.hpp>
|
||||||
#include <rotgen/container.hpp>
|
#include <rotgen/container.hpp>
|
||||||
#include <rotgen/alias.hpp>
|
#include <rotgen/alias.hpp>
|
||||||
#include <rotgen/algebra.hpp>
|
#include <rotgen/algebra.hpp>
|
||||||
#include <rotgen/functions.hpp>
|
#include <rotgen/functions.hpp>
|
||||||
|
//clang-format on
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@
|
||||||
struct CLASSNAME::payload
|
struct CLASSNAME::payload
|
||||||
{
|
{
|
||||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
using matrix_type = Eigen::Matrix<TYPE,Eigen::Dynamic,Eigen::Dynamic,STORAGE_ORDER>;
|
using matrix_type =
|
||||||
|
Eigen::Matrix<TYPE, Eigen::Dynamic, Eigen::Dynamic, STORAGE_ORDER>;
|
||||||
using matrix_block_type = Eigen::Block<matrix_type CONST>;
|
using matrix_block_type = Eigen::Block<matrix_type CONST>;
|
||||||
using matrix_storage_t = std::pair<matrix_block_type, matrix_type CONST*>;
|
using matrix_storage_t = std::pair<matrix_block_type, matrix_type CONST*>;
|
||||||
using map_type = Eigen::Map<matrix_type CONST, Eigen::Unaligned, stride_type>;
|
using map_type = Eigen::Map<matrix_type CONST, Eigen::Unaligned, stride_type>;
|
||||||
|
|
@ -32,35 +33,55 @@ struct CLASSNAME::payload
|
||||||
rotgen::Index rel_i0 = 0; // relative start row in original matrix
|
rotgen::Index rel_i0 = 0; // relative start row in original matrix
|
||||||
rotgen::Index rel_j0 = 0; // relative start col in original matrix
|
rotgen::Index rel_j0 = 0; // relative start col in original matrix
|
||||||
|
|
||||||
template <typename Func>
|
template<typename Func> void apply(Func f)
|
||||||
void apply(Func f) { std::visit([&](auto& blk) { return f(blk.first); }, data); }
|
{
|
||||||
|
std::visit([&](auto& blk) { return f(blk.first); }, data);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Func>
|
template<typename Func> void apply(Func f) const
|
||||||
void apply(Func f) const { std::visit([&](auto const& blk) { return f(blk.first); }, data); }
|
{
|
||||||
|
std::visit([&](auto const& blk) { return f(blk.first); }, data);
|
||||||
|
}
|
||||||
|
|
||||||
payload(data_type const& o) : data(o) {}
|
payload(data_type const& o) : data(o) {}
|
||||||
|
|
||||||
payload (SOURCENAME CONST& o, rotgen::Index i0, rotgen::Index j0, rotgen::Index ni, rotgen::Index nj)
|
payload(SOURCENAME CONST& o,
|
||||||
: data(matrix_storage_t{matrix_block_type{o.storage()->data,i0,j0,ni,nj},&o.storage()->data})
|
rotgen::Index i0,
|
||||||
, abs_i0(i0), abs_j0(j0), rel_i0(i0), rel_j0(j0)
|
rotgen::Index j0,
|
||||||
{}
|
rotgen::Index ni,
|
||||||
|
rotgen::Index nj)
|
||||||
|
: data(
|
||||||
|
matrix_storage_t{matrix_block_type{o.storage()->data, i0, j0, ni, nj},
|
||||||
|
&o.storage()->data}),
|
||||||
|
abs_i0(i0), abs_j0(j0), rel_i0(i0), rel_j0(j0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
payload (MAPNAME CONST& o, rotgen::Index i0, rotgen::Index j0, rotgen::Index ni, rotgen::Index nj)
|
payload(MAPNAME CONST& o,
|
||||||
: data(map_storage_t{map_block_type{o.storage()->data,i0,j0,ni,nj},&o.storage()->data})
|
rotgen::Index i0,
|
||||||
, abs_i0(i0), abs_j0(j0), rel_i0(i0), rel_j0(j0)
|
rotgen::Index j0,
|
||||||
{}
|
rotgen::Index ni,
|
||||||
|
rotgen::Index nj)
|
||||||
|
: data(map_storage_t{map_block_type{o.storage()->data, i0, j0, ni, nj},
|
||||||
|
&o.storage()->data}),
|
||||||
|
abs_i0(i0), abs_j0(j0), rel_i0(i0), rel_j0(j0)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Constructors & Special Members
|
// Constructors & Special Members
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
CLASSNAME::CLASSNAME(SOURCENAME CONST& r, Index i0, Index j0, Index ni, Index nj)
|
CLASSNAME::CLASSNAME(
|
||||||
|
SOURCENAME CONST& r, Index i0, Index j0, Index ni, Index nj)
|
||||||
: storage_(std::make_unique<payload>(r, i0, j0, ni, nj))
|
: storage_(std::make_unique<payload>(r, i0, j0, ni, nj))
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
CLASSNAME::CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj)
|
CLASSNAME::CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj)
|
||||||
: storage_(std::make_unique<payload>(r, i0, j0, ni, nj))
|
: storage_(std::make_unique<payload>(r, i0, j0, ni, nj))
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// We're building a block from a block - So we have to dig around the internals
|
// We're building a block from a block - So we have to dig around the internals
|
||||||
CLASSNAME::CLASSNAME(payload const& o, Index i0, Index j0, Index ni, Index nj)
|
CLASSNAME::CLASSNAME(payload const& o, Index i0, Index j0, Index ni, Index nj)
|
||||||
|
|
@ -68,22 +89,22 @@ struct CLASSNAME::payload
|
||||||
// Compute absolute indices from the parent stored block
|
// Compute absolute indices from the parent stored block
|
||||||
Index abs_i0 = 0;
|
Index abs_i0 = 0;
|
||||||
Index abs_j0 = 0;
|
Index abs_j0 = 0;
|
||||||
std::visit( [&](auto const& blk)
|
std::visit(
|
||||||
{
|
[&](auto const& blk) {
|
||||||
abs_i0 = blk.first.startRow() + i0;
|
abs_i0 = blk.first.startRow() + i0;
|
||||||
abs_j0 = blk.first.startCol() + j0;
|
abs_j0 = blk.first.startCol() + j0;
|
||||||
}
|
},
|
||||||
, o.data
|
o.data);
|
||||||
);
|
|
||||||
|
|
||||||
// Build a payload::data_type that holds the child block using absolute indices
|
// Build a payload::data_type that holds the child block using absolute
|
||||||
payload::data_type new_data =
|
// indices
|
||||||
std::visit([&]<typename T>(T const& blk) -> payload::data_type
|
payload::data_type new_data = std::visit(
|
||||||
{
|
[&]<typename T>(T const& blk) -> payload::data_type {
|
||||||
auto& [parent_block, ref] = blk;
|
auto& [parent_block, ref] = blk;
|
||||||
using block_type = typename T::first_type;
|
using block_type = typename T::first_type;
|
||||||
return T{block_type{*ref, abs_i0, abs_j0, ni, nj}, ref};
|
return T{block_type{*ref, abs_i0, abs_j0, ni, nj}, ref};
|
||||||
}, o.data);
|
},
|
||||||
|
o.data);
|
||||||
|
|
||||||
storage_ = std::make_unique<payload>(new_data);
|
storage_ = std::make_unique<payload>(new_data);
|
||||||
storage_->abs_i0 = abs_i0;
|
storage_->abs_i0 = abs_i0;
|
||||||
|
|
@ -94,7 +115,8 @@ struct CLASSNAME::payload
|
||||||
|
|
||||||
CLASSNAME::CLASSNAME(CLASSNAME const& o)
|
CLASSNAME::CLASSNAME(CLASSNAME const& o)
|
||||||
: storage_(std::make_unique<payload>(o.storage_->data))
|
: storage_(std::make_unique<payload>(o.storage_->data))
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
CLASSNAME::CLASSNAME(CLASSNAME&&) noexcept = default;
|
CLASSNAME::CLASSNAME(CLASSNAME&&) noexcept = default;
|
||||||
|
|
||||||
|
|
@ -112,16 +134,12 @@ struct CLASSNAME::payload
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
CLASSNAME::~CLASSNAME() = default;
|
CLASSNAME::~CLASSNAME() = default;
|
||||||
|
|
||||||
#if !defined(USE_CONST)
|
#if !defined(USE_CONST)
|
||||||
void CLASSNAME::assign(SOURCENAME const& m)
|
void CLASSNAME::assign(SOURCENAME const& m)
|
||||||
{
|
{
|
||||||
storage_->apply([&](auto& blk)
|
storage_->apply([&](auto& blk) { blk = m.storage()->data; });
|
||||||
{
|
|
||||||
blk = m.storage()->data;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -131,35 +149,35 @@ struct CLASSNAME::payload
|
||||||
rotgen::Index CLASSNAME::rows() const
|
rotgen::Index CLASSNAME::rows() const
|
||||||
{
|
{
|
||||||
rotgen::Index that;
|
rotgen::Index that;
|
||||||
storage_->apply([&](const auto& blk) { that = blk.rows(); });
|
storage_->apply([&](auto const& blk) { that = blk.rows(); });
|
||||||
return that;
|
return that;
|
||||||
}
|
}
|
||||||
|
|
||||||
rotgen::Index CLASSNAME::cols() const
|
rotgen::Index CLASSNAME::cols() const
|
||||||
{
|
{
|
||||||
rotgen::Index that;
|
rotgen::Index that;
|
||||||
storage_->apply([&](const auto& blk) { that = blk.cols(); });
|
storage_->apply([&](auto const& blk) { that = blk.cols(); });
|
||||||
return that;
|
return that;
|
||||||
}
|
}
|
||||||
|
|
||||||
rotgen::Index CLASSNAME::size() const
|
rotgen::Index CLASSNAME::size() const
|
||||||
{
|
{
|
||||||
rotgen::Index that;
|
rotgen::Index that;
|
||||||
storage_->apply([&](const auto& blk) { that = blk.size(); });
|
storage_->apply([&](auto const& blk) { that = blk.size(); });
|
||||||
return that;
|
return that;
|
||||||
}
|
}
|
||||||
|
|
||||||
rotgen::Index CLASSNAME::innerStride() const
|
rotgen::Index CLASSNAME::innerStride() const
|
||||||
{
|
{
|
||||||
rotgen::Index that;
|
rotgen::Index that;
|
||||||
storage_->apply([&](const auto& blk) { that = blk.innerStride(); });
|
storage_->apply([&](auto const& blk) { that = blk.innerStride(); });
|
||||||
return that;
|
return that;
|
||||||
}
|
}
|
||||||
|
|
||||||
rotgen::Index CLASSNAME::outerStride() const
|
rotgen::Index CLASSNAME::outerStride() const
|
||||||
{
|
{
|
||||||
rotgen::Index that;
|
rotgen::Index that;
|
||||||
storage_->apply([&](const auto& blk) { that = blk.outerStride(); });
|
storage_->apply([&](auto const& blk) { that = blk.outerStride(); });
|
||||||
return that;
|
return that;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -230,56 +248,66 @@ struct CLASSNAME::payload
|
||||||
SOURCENAME CLASSNAME::normalized() const
|
SOURCENAME CLASSNAME::normalized() const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
storage_->apply([&](const auto& blk) { result.storage()->assign(blk.normalized().eval()); });
|
storage_->apply([&](auto const& blk) {
|
||||||
|
result.storage()->assign(blk.normalized().eval());
|
||||||
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::transpose() const
|
SOURCENAME CLASSNAME::transpose() const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
storage_->apply([&](const auto& blk) { result.storage()->assign(blk.transpose().eval()); });
|
storage_->apply(
|
||||||
|
[&](auto const& blk) { result.storage()->assign(blk.transpose().eval()); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::conjugate() const
|
SOURCENAME CLASSNAME::conjugate() const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
storage_->apply([&](const auto& blk) { result.storage()->assign(blk.conjugate().eval()); });
|
storage_->apply(
|
||||||
|
[&](auto const& blk) { result.storage()->assign(blk.conjugate().eval()); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::adjoint() const
|
SOURCENAME CLASSNAME::adjoint() const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
storage_->apply([&](const auto& blk) { result.storage()->assign(blk.adjoint().eval()); });
|
storage_->apply(
|
||||||
|
[&](auto const& blk) { result.storage()->assign(blk.adjoint().eval()); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::cwiseAbs() const
|
SOURCENAME CLASSNAME::cwiseAbs() const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
storage_->apply([&](const auto& blk) { result.storage()->assign(blk.cwiseAbs().eval()); });
|
storage_->apply(
|
||||||
|
[&](auto const& blk) { result.storage()->assign(blk.cwiseAbs().eval()); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::cwiseAbs2() const
|
SOURCENAME CLASSNAME::cwiseAbs2() const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
storage_->apply([&](const auto& blk) { result.storage()->assign(blk.cwiseAbs2().eval()); });
|
storage_->apply(
|
||||||
|
[&](auto const& blk) { result.storage()->assign(blk.cwiseAbs2().eval()); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::cwiseInverse() const
|
SOURCENAME CLASSNAME::cwiseInverse() const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
storage_->apply([&](const auto& blk) { result.storage()->assign(blk.cwiseInverse().eval()); });
|
storage_->apply([&](auto const& blk) {
|
||||||
|
result.storage()->assign(blk.cwiseInverse().eval());
|
||||||
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::cwiseSqrt() const
|
SOURCENAME CLASSNAME::cwiseSqrt() const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
storage_->apply([&](const auto& blk) { result.storage()->assign(blk.cwiseSqrt().eval()); });
|
storage_->apply(
|
||||||
|
[&](auto const& blk) { result.storage()->assign(blk.cwiseSqrt().eval()); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -306,78 +334,77 @@ struct CLASSNAME::payload
|
||||||
TYPE CLASSNAME::sum() const
|
TYPE CLASSNAME::sum() const
|
||||||
{
|
{
|
||||||
TYPE val{};
|
TYPE val{};
|
||||||
storage_->apply([&](const auto& blk) { val = blk.sum(); });
|
storage_->apply([&](auto const& blk) { val = blk.sum(); });
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::prod() const
|
TYPE CLASSNAME::prod() const
|
||||||
{
|
{
|
||||||
TYPE val{};
|
TYPE val{};
|
||||||
storage_->apply([&](const auto& blk) { val = blk.prod(); });
|
storage_->apply([&](auto const& blk) { val = blk.prod(); });
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::mean() const
|
TYPE CLASSNAME::mean() const
|
||||||
{
|
{
|
||||||
TYPE val{};
|
TYPE val{};
|
||||||
storage_->apply([&](const auto& blk) { val = blk.mean(); });
|
storage_->apply([&](auto const& blk) { val = blk.mean(); });
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::trace() const
|
TYPE CLASSNAME::trace() const
|
||||||
{
|
{
|
||||||
TYPE val{};
|
TYPE val{};
|
||||||
storage_->apply([&](const auto& blk) { val = blk.trace(); });
|
storage_->apply([&](auto const& blk) { val = blk.trace(); });
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::minCoeff() const
|
TYPE CLASSNAME::minCoeff() const
|
||||||
{
|
{
|
||||||
TYPE val{};
|
TYPE val{};
|
||||||
storage_->apply([&](const auto& blk) { val = blk.minCoeff(); });
|
storage_->apply([&](auto const& blk) { val = blk.minCoeff(); });
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::maxCoeff() const
|
TYPE CLASSNAME::maxCoeff() const
|
||||||
{
|
{
|
||||||
TYPE val{};
|
TYPE val{};
|
||||||
storage_->apply([&](const auto& blk) { val = blk.maxCoeff(); });
|
storage_->apply([&](auto const& blk) { val = blk.maxCoeff(); });
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::minCoeff(Index* row, Index* col) const
|
TYPE CLASSNAME::minCoeff(Index* row, Index* col) const
|
||||||
{
|
{
|
||||||
TYPE val{};
|
TYPE val{};
|
||||||
storage_->apply([&](const auto& blk) { val = blk.minCoeff(row, col); });
|
storage_->apply([&](auto const& blk) { val = blk.minCoeff(row, col); });
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::maxCoeff(Index* row, Index* col) const
|
TYPE CLASSNAME::maxCoeff(Index* row, Index* col) const
|
||||||
{
|
{
|
||||||
TYPE val{};
|
TYPE val{};
|
||||||
storage_->apply([&](const auto& blk) { val = blk.maxCoeff(row, col); });
|
storage_->apply([&](auto const& blk) { val = blk.maxCoeff(row, col); });
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::squaredNorm() const
|
TYPE CLASSNAME::squaredNorm() const
|
||||||
{
|
{
|
||||||
TYPE val{};
|
TYPE val{};
|
||||||
storage_->apply([&](const auto& blk) { val = blk.squaredNorm(); });
|
storage_->apply([&](auto const& blk) { val = blk.squaredNorm(); });
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::norm() const
|
TYPE CLASSNAME::norm() const
|
||||||
{
|
{
|
||||||
TYPE val{};
|
TYPE val{};
|
||||||
storage_->apply([&](const auto& blk) { val = blk.norm(); });
|
storage_->apply([&](auto const& blk) { val = blk.norm(); });
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::lpNorm(int p) const
|
TYPE CLASSNAME::lpNorm(int p) const
|
||||||
{
|
{
|
||||||
TYPE val{};
|
TYPE val{};
|
||||||
storage_->apply([&](const auto& blk)
|
storage_->apply([&](auto const& blk) {
|
||||||
{
|
|
||||||
if (p == 1) val = blk.template lpNorm<1>();
|
if (p == 1) val = blk.template lpNorm<1>();
|
||||||
else if (p == 2) val = blk.template lpNorm<2>();
|
else if (p == 2) val = blk.template lpNorm<2>();
|
||||||
else val = blk.template lpNorm<Eigen::Infinity>();
|
else val = blk.template lpNorm<Eigen::Infinity>();
|
||||||
|
|
@ -390,65 +417,65 @@ struct CLASSNAME::payload
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os, CLASSNAME const& m)
|
ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os, CLASSNAME const& m)
|
||||||
{
|
{
|
||||||
m.storage_->apply([&](const auto& blk) { os << blk; });
|
m.storage_->apply([&](auto const& blk) { os << blk; });
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os,format<CLASSNAME> const& m)
|
ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os,
|
||||||
|
format<CLASSNAME> const& m)
|
||||||
{
|
{
|
||||||
m.matrix_.storage_->apply([&](const auto& blk) { os << blk.format(m.format_.storage()->instance); });
|
m.matrix_.storage_->apply(
|
||||||
|
[&](auto const& blk) { os << blk.format(m.format_.storage()->instance); });
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs)
|
ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
return std::visit ( [](auto const& lhs_blk, auto const& rhs_blk) { return lhs_blk.first == rhs_blk.first; }
|
return std::visit(
|
||||||
, lhs.storage_->data
|
[](auto const& lhs_blk, auto const& rhs_blk) {
|
||||||
, rhs.storage_->data
|
return lhs_blk.first == rhs_blk.first;
|
||||||
);
|
},
|
||||||
|
lhs.storage_->data, rhs.storage_->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
ROTGEN_EXPORT bool operator!=(CLASSNAME const& lhs, CLASSNAME const& rhs)
|
ROTGEN_EXPORT bool operator!=(CLASSNAME const& lhs, CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
return std::visit ( [](auto const& lhs_blk, auto const& rhs_blk) { return lhs_blk.first != rhs_blk.first; }
|
return std::visit(
|
||||||
, lhs.storage_->data
|
[](auto const& lhs_blk, auto const& rhs_blk) {
|
||||||
, rhs.storage_->data
|
return lhs_blk.first != rhs_blk.first;
|
||||||
);
|
},
|
||||||
|
lhs.storage_->data, rhs.storage_->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::operator-() const
|
SOURCENAME CLASSNAME::operator-() const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
storage_->apply([&](const auto& blk) { result.storage()->assign(blk); });
|
storage_->apply([&](auto const& blk) { result.storage()->assign(blk); });
|
||||||
return -result;
|
return -result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(USE_CONST)
|
#if !defined(USE_CONST)
|
||||||
CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
|
CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
std::visit( [](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first += rhs_blk.first; }
|
std::visit(
|
||||||
, storage_->data
|
[](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first += rhs_blk.first; },
|
||||||
, rhs.storage_->data
|
storage_->data, rhs.storage_->data);
|
||||||
);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
|
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
std::visit( [](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first -= rhs_blk.first; }
|
std::visit(
|
||||||
, storage_->data
|
[](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first -= rhs_blk.first; },
|
||||||
, rhs.storage_->data
|
storage_->data, rhs.storage_->data);
|
||||||
);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
|
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
std::visit( [](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first *= rhs_blk.first; }
|
std::visit(
|
||||||
, storage_->data
|
[](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first *= rhs_blk.first; },
|
||||||
, rhs.storage_->data
|
storage_->data, rhs.storage_->data);
|
||||||
);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -468,67 +495,50 @@ struct CLASSNAME::payload
|
||||||
SOURCENAME CLASSNAME::add(CLASSNAME const& rhs) const
|
SOURCENAME CLASSNAME::add(CLASSNAME const& rhs) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign( std::visit( [](auto const& lhs_blk, auto const& rhs_blk)
|
result.storage()->assign(std::visit(
|
||||||
{
|
[](auto const& lhs_blk, auto const& rhs_blk) {
|
||||||
return (lhs_blk.first + rhs_blk.first).eval();
|
return (lhs_blk.first + rhs_blk.first).eval();
|
||||||
}
|
},
|
||||||
, storage_->data
|
storage_->data, rhs.storage_->data));
|
||||||
, rhs.storage_->data
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::sub(CLASSNAME const& rhs) const
|
SOURCENAME CLASSNAME::sub(CLASSNAME const& rhs) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign( std::visit( [](auto const& lhs_blk, auto const& rhs_blk)
|
result.storage()->assign(std::visit(
|
||||||
{
|
[](auto const& lhs_blk, auto const& rhs_blk) {
|
||||||
return (lhs_blk.first - rhs_blk.first).eval();
|
return (lhs_blk.first - rhs_blk.first).eval();
|
||||||
}
|
},
|
||||||
, storage_->data
|
storage_->data, rhs.storage_->data));
|
||||||
, rhs.storage_->data
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::mul(CLASSNAME const& rhs) const
|
SOURCENAME CLASSNAME::mul(CLASSNAME const& rhs) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign( std::visit( [](auto const& lhs_blk, auto const& rhs_blk)
|
result.storage()->assign(std::visit(
|
||||||
{
|
[](auto const& lhs_blk, auto const& rhs_blk) {
|
||||||
return (lhs_blk.first * rhs_blk.first).eval();
|
return (lhs_blk.first * rhs_blk.first).eval();
|
||||||
}
|
},
|
||||||
, storage_->data
|
storage_->data, rhs.storage_->data));
|
||||||
, rhs.storage_->data
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::mul(TYPE s) const
|
SOURCENAME CLASSNAME::mul(TYPE s) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign( std::visit( [s](auto const& lhs_blk)
|
result.storage()->assign(
|
||||||
{
|
std::visit([s](auto const& lhs_blk) { return (lhs_blk.first * s).eval(); },
|
||||||
return (lhs_blk.first * s).eval();
|
storage_->data));
|
||||||
}
|
|
||||||
, storage_->data
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::div(TYPE s) const
|
SOURCENAME CLASSNAME::div(TYPE s) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign( std::visit( [s](auto const& lhs_blk)
|
result.storage()->assign(
|
||||||
{
|
std::visit([s](auto const& lhs_blk) { return (lhs_blk.first / s).eval(); },
|
||||||
return (lhs_blk.first / s).eval();
|
storage_->data));
|
||||||
}
|
|
||||||
, storage_->data
|
|
||||||
)
|
|
||||||
);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,18 @@
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
ioformat::ioformat( int p, int f
|
ioformat::ioformat(int p,
|
||||||
, std::string const& cs, std::string const& rsp
|
int f,
|
||||||
, std::string const& rp, std::string const& rs
|
std::string const& cs,
|
||||||
, std::string const& mp, std::string const& ms
|
std::string const& rsp,
|
||||||
, char fill
|
std::string const& rp,
|
||||||
)
|
std::string const& rs,
|
||||||
|
std::string const& mp,
|
||||||
|
std::string const& ms,
|
||||||
|
char fill)
|
||||||
: storage_(std::make_unique<payload>(p, f, cs, rsp, rp, rs, mp, ms, fill))
|
: storage_(std::make_unique<payload>(p, f, cs, rsp, rp, rs, mp, ms, fill))
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ioformat::~ioformat() = default;
|
ioformat::~ioformat() = default;
|
||||||
}
|
}
|
||||||
|
|
@ -12,7 +12,8 @@ namespace rotgen::detail
|
||||||
{
|
{
|
||||||
ROTGEN_EXPORT std::ostream& dynamic_info(std::ostream& os)
|
ROTGEN_EXPORT std::ostream& dynamic_info(std::ostream& os)
|
||||||
{
|
{
|
||||||
if constexpr(rotgen::is_forcing_dynamic_status) return os << "[ROTGEN] - Fully Dynamic mode with:" << std::endl;
|
if constexpr (rotgen::is_forcing_dynamic_status)
|
||||||
|
return os << "[ROTGEN] - Fully Dynamic mode with:" << std::endl;
|
||||||
else return os << "[ROTGEN] - Flexible mode with:" << std::endl;
|
else return os << "[ROTGEN] - Flexible mode with:" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -19,15 +19,21 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Constructors & Special Members
|
// Constructors & Special Members
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
CLASSNAME::CLASSNAME(TYPE CONST* ptr, Index r, Index c) : storage_(std::make_unique<payload>(ptr,r,c))
|
CLASSNAME::CLASSNAME(TYPE CONST* ptr, Index r, Index c)
|
||||||
{}
|
: storage_(std::make_unique<payload>(ptr, r, c))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
CLASSNAME::CLASSNAME(TYPE CONST* ptr, Index r, Index c, stride s)
|
CLASSNAME::CLASSNAME(TYPE CONST* ptr, Index r, Index c, stride s)
|
||||||
: storage_(std::make_unique<payload>(ptr,r,c,payload::stride_type{s.outer(),s.inner()}))
|
: storage_(std::make_unique<payload>(
|
||||||
{}
|
ptr, r, c, payload::stride_type{s.outer(), s.inner()}))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
CLASSNAME::CLASSNAME(CLASSNAME const& o) : storage_(std::make_unique<payload>(o.storage_->data))
|
CLASSNAME::CLASSNAME(CLASSNAME const& o)
|
||||||
{}
|
: storage_(std::make_unique<payload>(o.storage_->data))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(USE_CONST)
|
#if !defined(USE_CONST)
|
||||||
CLASSNAME& CLASSNAME::operator=(CLASSNAME const& o)
|
CLASSNAME& CLASSNAME::operator=(CLASSNAME const& o)
|
||||||
|
|
@ -50,22 +56,62 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Matrix API
|
// Matrix API
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
rotgen::Index CLASSNAME::rows() const { return storage_->data.rows(); }
|
rotgen::Index CLASSNAME::rows() const
|
||||||
rotgen::Index CLASSNAME::cols() const { return storage_->data.cols(); }
|
{
|
||||||
rotgen::Index CLASSNAME::size() const { return storage_->data.size(); }
|
return storage_->data.rows();
|
||||||
rotgen::Index CLASSNAME::innerStride() const { return storage_->data.innerStride(); }
|
}
|
||||||
rotgen::Index CLASSNAME::outerStride() const { return storage_->data.outerStride(); }
|
|
||||||
|
|
||||||
const TYPE* CLASSNAME::data() const { return storage_->data.data(); }
|
rotgen::Index CLASSNAME::cols() const
|
||||||
|
{
|
||||||
|
return storage_->data.cols();
|
||||||
|
}
|
||||||
|
|
||||||
|
rotgen::Index CLASSNAME::size() const
|
||||||
|
{
|
||||||
|
return storage_->data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
rotgen::Index CLASSNAME::innerStride() const
|
||||||
|
{
|
||||||
|
return storage_->data.innerStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
rotgen::Index CLASSNAME::outerStride() const
|
||||||
|
{
|
||||||
|
return storage_->data.outerStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
const TYPE* CLASSNAME::data() const
|
||||||
|
{
|
||||||
|
return storage_->data.data();
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(USE_CONST)
|
#if !defined(USE_CONST)
|
||||||
TYPE* CLASSNAME::data() { return storage_->data.data(); }
|
TYPE* CLASSNAME::data()
|
||||||
TYPE& CLASSNAME::operator()(Index i, Index j) { return storage_->data(i,j); }
|
{
|
||||||
TYPE& CLASSNAME::operator()(Index i) { return storage_->data.data()[i]; }
|
return storage_->data.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE& CLASSNAME::operator()(Index i, Index j)
|
||||||
|
{
|
||||||
|
return storage_->data(i, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE& CLASSNAME::operator()(Index i)
|
||||||
|
{
|
||||||
|
return storage_->data.data()[i];
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TYPE CLASSNAME::operator()(Index i, Index j) const { return storage_->data(i,j); }
|
TYPE CLASSNAME::operator()(Index i, Index j) const
|
||||||
TYPE CLASSNAME::operator()(Index i) const { return storage_->data.data()[i]; }
|
{
|
||||||
|
return storage_->data(i, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::operator()(Index i) const
|
||||||
|
{
|
||||||
|
return storage_->data.data()[i];
|
||||||
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::normalized() const
|
SOURCENAME CLASSNAME::normalized() const
|
||||||
{
|
{
|
||||||
|
|
@ -140,14 +186,16 @@
|
||||||
SOURCENAME CLASSNAME::cwiseProduct(CLASSNAME const& rhs) const
|
SOURCENAME CLASSNAME::cwiseProduct(CLASSNAME const& rhs) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign(storage_->data.cwiseProduct(rhs.storage()->data).eval());
|
result.storage()->assign(
|
||||||
|
storage_->data.cwiseProduct(rhs.storage()->data).eval());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::cwiseQuotient(CLASSNAME const& rhs) const
|
SOURCENAME CLASSNAME::cwiseQuotient(CLASSNAME const& rhs) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign(storage_->data.cwiseQuotient(rhs.storage()->data).eval());
|
result.storage()->assign(
|
||||||
|
storage_->data.cwiseQuotient(rhs.storage()->data).eval());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,19 +247,55 @@
|
||||||
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
|
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::sum() const { return storage_->data.sum(); }
|
TYPE CLASSNAME::sum() const
|
||||||
TYPE CLASSNAME::prod() const { return storage_->data.prod(); }
|
{
|
||||||
TYPE CLASSNAME::mean() const { return storage_->data.mean(); }
|
return storage_->data.sum();
|
||||||
TYPE CLASSNAME::trace() const { return storage_->data.trace(); }
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::minCoeff() const { return storage_->data.minCoeff(); }
|
TYPE CLASSNAME::prod() const
|
||||||
TYPE CLASSNAME::maxCoeff() const { return storage_->data.maxCoeff(); }
|
{
|
||||||
|
return storage_->data.prod();
|
||||||
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::minCoeff(Index* row, Index* col) const { return storage_->data.minCoeff(row, col); }
|
TYPE CLASSNAME::mean() const
|
||||||
TYPE CLASSNAME::maxCoeff(Index* row, Index* col) const { return storage_->data.maxCoeff(row, col); }
|
{
|
||||||
|
return storage_->data.mean();
|
||||||
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::squaredNorm() const { return storage_->data.squaredNorm(); }
|
TYPE CLASSNAME::trace() const
|
||||||
TYPE CLASSNAME::norm() const { return storage_->data.norm(); }
|
{
|
||||||
|
return storage_->data.trace();
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::minCoeff() const
|
||||||
|
{
|
||||||
|
return storage_->data.minCoeff();
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::maxCoeff() const
|
||||||
|
{
|
||||||
|
return storage_->data.maxCoeff();
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::minCoeff(Index* row, Index* col) const
|
||||||
|
{
|
||||||
|
return storage_->data.minCoeff(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::maxCoeff(Index* row, Index* col) const
|
||||||
|
{
|
||||||
|
return storage_->data.maxCoeff(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::squaredNorm() const
|
||||||
|
{
|
||||||
|
return storage_->data.squaredNorm();
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::norm() const
|
||||||
|
{
|
||||||
|
return storage_->data.norm();
|
||||||
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::lpNorm(int p) const
|
TYPE CLASSNAME::lpNorm(int p) const
|
||||||
{
|
{
|
||||||
|
|
@ -253,7 +337,8 @@
|
||||||
SOURCENAME CLASSNAME::qr_solve(CLASSNAME const& rhs) const
|
SOURCENAME CLASSNAME::qr_solve(CLASSNAME const& rhs) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign(storage_->data.colPivHouseholderQr().solve(rhs.storage_->data).eval());
|
result.storage()->assign(
|
||||||
|
storage_->data.colPivHouseholderQr().solve(rhs.storage_->data).eval());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -265,7 +350,8 @@
|
||||||
return os << m.storage_->data;
|
return os << m.storage_->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os,format<CLASSNAME> const& m)
|
ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os,
|
||||||
|
format<CLASSNAME> const& m)
|
||||||
{
|
{
|
||||||
return os << m.matrix_.storage_->data.format(m.format_.storage()->instance);
|
return os << m.matrix_.storage_->data.format(m.format_.storage()->instance);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,27 +11,74 @@
|
||||||
#include <Eigen/Dense>
|
#include <Eigen/Dense>
|
||||||
|
|
||||||
#define ROTGEN_IMPL_OP(OP, FN, RET) \
|
#define ROTGEN_IMPL_OP(OP, FN, RET) \
|
||||||
RET operator OP(map_const_impl32_col const& a, map_impl32_col const& b ) { return FN(a, b); } \
|
RET operator OP(map_const_impl32_col const& a, map_impl32_col const& b) \
|
||||||
RET operator OP(map_const_impl32_col const& a, map_impl32_row const& b ) { return FN(a, b); } \
|
{ \
|
||||||
RET operator OP(map_const_impl32_col const& a, map_const_impl32_row const& b ) { return FN(a, b); } \
|
return FN(a, b); \
|
||||||
RET operator OP(map_const_impl32_row const& a, map_impl32_row const& b ) { return FN(a, b); } \
|
} \
|
||||||
RET operator OP(map_const_impl32_row const& a, map_impl32_col const& b ) { return FN(a, b); } \
|
RET operator OP(map_const_impl32_col const& a, map_impl32_row const& b) \
|
||||||
RET operator OP(map_impl32_col const& a, map_impl32_row const& b ) { return FN(a, b); } \
|
{ \
|
||||||
RET operator OP(map_const_impl64_col const& a, map_impl64_col const& b ) { return FN(a, b); } \
|
return FN(a, b); \
|
||||||
RET operator OP(map_const_impl64_col const& a, map_impl64_row const& b ) { return FN(a, b); } \
|
} \
|
||||||
RET operator OP(map_const_impl64_col const& a, map_const_impl64_row const& b ) { return FN(a, b); } \
|
RET operator OP(map_const_impl32_col const& a, \
|
||||||
RET operator OP(map_const_impl64_row const& a, map_impl64_row const& b ) { return FN(a, b); } \
|
map_const_impl32_row const& b) \
|
||||||
RET operator OP(map_const_impl64_row const& a, map_impl64_col const& b ) { return FN(a, b); } \
|
{ \
|
||||||
RET operator OP(map_impl64_col const& a, map_impl64_row const& b ) { return FN(a, b); } \
|
return FN(a, b); \
|
||||||
|
} \
|
||||||
|
RET operator OP(map_const_impl32_row const& a, map_impl32_row const& b) \
|
||||||
|
{ \
|
||||||
|
return FN(a, b); \
|
||||||
|
} \
|
||||||
|
RET operator OP(map_const_impl32_row const& a, map_impl32_col const& b) \
|
||||||
|
{ \
|
||||||
|
return FN(a, b); \
|
||||||
|
} \
|
||||||
|
RET operator OP(map_impl32_col const& a, map_impl32_row const& b) \
|
||||||
|
{ \
|
||||||
|
return FN(a, b); \
|
||||||
|
} \
|
||||||
|
RET operator OP(map_const_impl64_col const& a, map_impl64_col const& b) \
|
||||||
|
{ \
|
||||||
|
return FN(a, b); \
|
||||||
|
} \
|
||||||
|
RET operator OP(map_const_impl64_col const& a, map_impl64_row const& b) \
|
||||||
|
{ \
|
||||||
|
return FN(a, b); \
|
||||||
|
} \
|
||||||
|
RET operator OP(map_const_impl64_col const& a, \
|
||||||
|
map_const_impl64_row const& b) \
|
||||||
|
{ \
|
||||||
|
return FN(a, b); \
|
||||||
|
} \
|
||||||
|
RET operator OP(map_const_impl64_row const& a, map_impl64_row const& b) \
|
||||||
|
{ \
|
||||||
|
return FN(a, b); \
|
||||||
|
} \
|
||||||
|
RET operator OP(map_const_impl64_row const& a, map_impl64_col const& b) \
|
||||||
|
{ \
|
||||||
|
return FN(a, b); \
|
||||||
|
} \
|
||||||
|
RET operator OP(map_impl64_col const& a, map_impl64_row const& b) \
|
||||||
|
{ \
|
||||||
|
return FN(a, b); \
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
bool equal(auto const& a, auto const& b) { return a.storage()->data == b.storage()->data; }
|
bool equal(auto const& a, auto const& b)
|
||||||
bool not_equal(auto const& a, auto const& b) { return a.storage()->data != b.storage()->data; }
|
{
|
||||||
|
return a.storage()->data == b.storage()->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool not_equal(auto const& a, auto const& b)
|
||||||
|
{
|
||||||
|
return a.storage()->data != b.storage()->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ROTGEN_IMPL_OP(==, equal, bool);
|
ROTGEN_IMPL_OP(==, equal, bool);
|
||||||
ROTGEN_IMPL_OP(!=, not_equal, bool);
|
ROTGEN_IMPL_OP(!=, not_equal, bool);
|
||||||
}
|
}
|
||||||
|
|
@ -16,29 +16,33 @@
|
||||||
// Constructors & Special Members
|
// Constructors & Special Members
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
CLASSNAME::CLASSNAME() : storage_(std::make_unique<payload>(0, 0)) {}
|
CLASSNAME::CLASSNAME() : storage_(std::make_unique<payload>(0, 0)) {}
|
||||||
CLASSNAME::CLASSNAME(std::size_t r, std::size_t c) : storage_(std::make_unique<payload>(r,c)) {}
|
|
||||||
|
CLASSNAME::CLASSNAME(std::size_t r, std::size_t c)
|
||||||
|
: storage_(std::make_unique<payload>(r, c))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
CLASSNAME::CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init)
|
CLASSNAME::CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init)
|
||||||
: storage_(std::make_unique<payload>(init))
|
: storage_(std::make_unique<payload>(init))
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
CLASSNAME::CLASSNAME(std::size_t r, std::size_t c,std::initializer_list<TYPE> init)
|
CLASSNAME::CLASSNAME(std::size_t r,
|
||||||
|
std::size_t c,
|
||||||
|
std::initializer_list<TYPE> init)
|
||||||
: CLASSNAME(r, c)
|
: CLASSNAME(r, c)
|
||||||
{
|
{
|
||||||
auto first = init.begin();
|
auto first = init.begin();
|
||||||
for(std::size_t i=0; i < init.size(); i++)
|
for (std::size_t i = 0; i < init.size(); i++) (*this)(i) = first[i];
|
||||||
(*this)(i) = first[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASSNAME::CLASSNAME(CLASSNAME const& o)
|
CLASSNAME::CLASSNAME(CLASSNAME const& o) : CLASSNAME(o.rows(), o.cols())
|
||||||
: CLASSNAME(o.rows(),o.cols())
|
|
||||||
{
|
{
|
||||||
storage_->data = o.storage_->data;
|
storage_->data = o.storage_->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASSNAME::CLASSNAME(CLASSNAME&&) noexcept = default;
|
CLASSNAME::CLASSNAME(CLASSNAME&&) noexcept = default;
|
||||||
|
|
||||||
|
|
||||||
CLASSNAME& CLASSNAME::operator=(CLASSNAME const& o)
|
CLASSNAME& CLASSNAME::operator=(CLASSNAME const& o)
|
||||||
{
|
{
|
||||||
if (this != &o) storage_->data = o.storage_->data;
|
if (this != &o) storage_->data = o.storage_->data;
|
||||||
|
|
@ -52,9 +56,20 @@ CLASSNAME::~CLASSNAME() = default;
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Matrix API
|
// Matrix API
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
rotgen::Index CLASSNAME::rows() const { return storage_->data.rows(); }
|
rotgen::Index CLASSNAME::rows() const
|
||||||
rotgen::Index CLASSNAME::cols() const { return storage_->data.cols(); }
|
{
|
||||||
rotgen::Index CLASSNAME::size() const { return storage_->data.size(); }
|
return storage_->data.rows();
|
||||||
|
}
|
||||||
|
|
||||||
|
rotgen::Index CLASSNAME::cols() const
|
||||||
|
{
|
||||||
|
return storage_->data.cols();
|
||||||
|
}
|
||||||
|
|
||||||
|
rotgen::Index CLASSNAME::size() const
|
||||||
|
{
|
||||||
|
return storage_->data.size();
|
||||||
|
}
|
||||||
|
|
||||||
void CLASSNAME::resize(std::size_t new_rows, std::size_t new_cols)
|
void CLASSNAME::resize(std::size_t new_rows, std::size_t new_cols)
|
||||||
{
|
{
|
||||||
|
|
@ -66,14 +81,35 @@ void CLASSNAME::conservativeResize(std::size_t new_rows, std::size_t new_cols)
|
||||||
storage_->data.conservativeResize(new_rows, new_cols);
|
storage_->data.conservativeResize(new_rows, new_cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE& CLASSNAME::operator()(std::size_t i, std::size_t j) { return storage_->data(i,j); }
|
TYPE& CLASSNAME::operator()(std::size_t i, std::size_t j)
|
||||||
TYPE const& CLASSNAME::operator()(std::size_t i, std::size_t j) const { return storage_->data(i,j); }
|
{
|
||||||
|
return storage_->data(i, j);
|
||||||
|
}
|
||||||
|
|
||||||
TYPE& CLASSNAME::operator()(std::size_t index) { return storage_->data(index); }
|
TYPE const& CLASSNAME::operator()(std::size_t i, std::size_t j) const
|
||||||
TYPE const& CLASSNAME::operator()(std::size_t index) const { return storage_->data(index); }
|
{
|
||||||
|
return storage_->data(i, j);
|
||||||
|
}
|
||||||
|
|
||||||
const TYPE* CLASSNAME::data() const { return storage_->data.data(); }
|
TYPE& CLASSNAME::operator()(std::size_t index)
|
||||||
TYPE* CLASSNAME::data() { return storage_->data.data(); }
|
{
|
||||||
|
return storage_->data(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE const& CLASSNAME::operator()(std::size_t index) const
|
||||||
|
{
|
||||||
|
return storage_->data(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
const TYPE* CLASSNAME::data() const
|
||||||
|
{
|
||||||
|
return storage_->data.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE* CLASSNAME::data()
|
||||||
|
{
|
||||||
|
return storage_->data.data();
|
||||||
|
}
|
||||||
|
|
||||||
CLASSNAME CLASSNAME::normalized() const
|
CLASSNAME CLASSNAME::normalized() const
|
||||||
{
|
{
|
||||||
|
|
@ -146,19 +182,55 @@ CLASSNAME CLASSNAME::cwiseSqrt() const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::sum() const { return storage_->data.sum(); }
|
TYPE CLASSNAME::sum() const
|
||||||
TYPE CLASSNAME::prod() const { return storage_->data.prod(); }
|
{
|
||||||
TYPE CLASSNAME::mean() const { return storage_->data.mean(); }
|
return storage_->data.sum();
|
||||||
TYPE CLASSNAME::trace() const { return storage_->data.trace(); }
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::minCoeff() const { return storage_->data.minCoeff(); }
|
TYPE CLASSNAME::prod() const
|
||||||
TYPE CLASSNAME::maxCoeff() const { return storage_->data.maxCoeff(); }
|
{
|
||||||
|
return storage_->data.prod();
|
||||||
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::minCoeff(Index* row, Index* col) const { return storage_->data.minCoeff(row, col); }
|
TYPE CLASSNAME::mean() const
|
||||||
TYPE CLASSNAME::maxCoeff(Index* row, Index* col) const { return storage_->data.maxCoeff(row, col); }
|
{
|
||||||
|
return storage_->data.mean();
|
||||||
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::squaredNorm() const { return storage_->data.squaredNorm(); }
|
TYPE CLASSNAME::trace() const
|
||||||
TYPE CLASSNAME::norm() const { return storage_->data.norm(); }
|
{
|
||||||
|
return storage_->data.trace();
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::minCoeff() const
|
||||||
|
{
|
||||||
|
return storage_->data.minCoeff();
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::maxCoeff() const
|
||||||
|
{
|
||||||
|
return storage_->data.maxCoeff();
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::minCoeff(Index* row, Index* col) const
|
||||||
|
{
|
||||||
|
return storage_->data.minCoeff(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::maxCoeff(Index* row, Index* col) const
|
||||||
|
{
|
||||||
|
return storage_->data.maxCoeff(row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::squaredNorm() const
|
||||||
|
{
|
||||||
|
return storage_->data.squaredNorm();
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::norm() const
|
||||||
|
{
|
||||||
|
return storage_->data.norm();
|
||||||
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::lp_norm(int p) const
|
TYPE CLASSNAME::lp_norm(int p) const
|
||||||
{
|
{
|
||||||
|
|
@ -175,7 +247,8 @@ ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os,CLASSNAME const& m)
|
||||||
return os << m.storage_->data;
|
return os << m.storage_->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os,format<CLASSNAME> const& m)
|
ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os,
|
||||||
|
format<CLASSNAME> const& m)
|
||||||
{
|
{
|
||||||
return os << m.matrix_.storage_->data.format(m.format_.storage()->instance);
|
return os << m.matrix_.storage_->data.format(m.format_.storage()->instance);
|
||||||
}
|
}
|
||||||
|
|
@ -248,20 +321,23 @@ CLASSNAME CLASSNAME::Zero(std::size_t rows, std::size_t cols)
|
||||||
CLASSNAME CLASSNAME::Constant(std::size_t rows, std::size_t cols, TYPE value)
|
CLASSNAME CLASSNAME::Constant(std::size_t rows, std::size_t cols, TYPE value)
|
||||||
{
|
{
|
||||||
CLASSNAME m;
|
CLASSNAME m;
|
||||||
m.storage_ = std::make_unique<payload>(payload::data_type::Constant(rows, cols, value));
|
m.storage_ =
|
||||||
|
std::make_unique<payload>(payload::data_type::Constant(rows, cols, value));
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASSNAME CLASSNAME::Random(std::size_t rows, std::size_t cols)
|
CLASSNAME CLASSNAME::Random(std::size_t rows, std::size_t cols)
|
||||||
{
|
{
|
||||||
CLASSNAME m;
|
CLASSNAME m;
|
||||||
m.storage_ = std::make_unique<payload>(payload::data_type::Random(rows, cols));
|
m.storage_ =
|
||||||
|
std::make_unique<payload>(payload::data_type::Random(rows, cols));
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASSNAME CLASSNAME::Identity(std::size_t rows, std::size_t cols)
|
CLASSNAME CLASSNAME::Identity(std::size_t rows, std::size_t cols)
|
||||||
{
|
{
|
||||||
CLASSNAME m;
|
CLASSNAME m;
|
||||||
m.storage_ = std::make_unique<payload>(payload::data_type::Identity(rows, cols));
|
m.storage_ =
|
||||||
|
std::make_unique<payload>(payload::data_type::Identity(rows, cols));
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
@ -17,10 +17,14 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
struct CLASSNAME::payload
|
struct CLASSNAME::payload
|
||||||
{
|
{
|
||||||
using matrix_type = Eigen::Matrix<TYPE,Eigen::Dynamic,Eigen::Dynamic,STORAGE_ORDER>;
|
using matrix_type =
|
||||||
|
Eigen::Matrix<TYPE, Eigen::Dynamic, Eigen::Dynamic, STORAGE_ORDER>;
|
||||||
Eigen::JacobiSVD<matrix_type> data;
|
Eigen::JacobiSVD<matrix_type> data;
|
||||||
|
|
||||||
payload(SOURCENAME const& src, int options) : data(src.storage()->data,options) {}
|
payload(SOURCENAME const& src, int options)
|
||||||
|
: data(src.storage()->data, options)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
@ -28,8 +32,8 @@ struct CLASSNAME::payload
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
CLASSNAME::CLASSNAME(SOURCENAME const& m, int options)
|
CLASSNAME::CLASSNAME(SOURCENAME const& m, int options)
|
||||||
: storage_(std::make_unique<payload>(m, options))
|
: storage_(std::make_unique<payload>(m, options))
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
CLASSNAME::CLASSNAME(CLASSNAME const& o)
|
CLASSNAME::CLASSNAME(CLASSNAME const& o)
|
||||||
: storage_(std::make_unique<payload>(*o.storage_))
|
: storage_(std::make_unique<payload>(*o.storage_))
|
||||||
|
|
@ -52,7 +56,10 @@ CLASSNAME& CLASSNAME::operator=(CLASSNAME&& o) noexcept
|
||||||
|
|
||||||
CLASSNAME::~CLASSNAME() = default;
|
CLASSNAME::~CLASSNAME() = default;
|
||||||
|
|
||||||
int CLASSNAME::rank() const { return storage_->data.rank(); }
|
int CLASSNAME::rank() const
|
||||||
|
{
|
||||||
|
return storage_->data.rank();
|
||||||
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::U() const
|
SOURCENAME CLASSNAME::U() const
|
||||||
{
|
{
|
||||||
|
|
@ -92,7 +99,8 @@ SOURCENAME CLASSNAME::D() const
|
||||||
SOURCENAME CLASSNAME::D(int r) const
|
SOURCENAME CLASSNAME::D(int r) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign(storage_->data.singularValues().head(r).asDiagonal());
|
result.storage()->assign(
|
||||||
|
storage_->data.singularValues().head(r).asDiagonal());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,16 @@
|
||||||
#include "unit/tests.hpp"
|
#include "unit/tests.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("noalias behavior - dynamicallly sized", rotgen::tests::types)
|
TTS_CASE_TPL("noalias behavior - dynamicallly sized",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> a{{1,2},{3,4}};
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a{{1, 2},
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> ref{{7,10},{15,22}};
|
{3, 4}};
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> b(2,2),c(2,2),d(2,2);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> ref{{7, 10},
|
||||||
|
{15, 22}};
|
||||||
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b(2, 2),
|
||||||
|
c(2, 2), d(2, 2);
|
||||||
|
|
||||||
rotgen::noalias(b) = a * a;
|
rotgen::noalias(b) = a * a;
|
||||||
TTS_EQUAL(b, ref);
|
TTS_EQUAL(b, ref);
|
||||||
|
|
@ -22,13 +26,15 @@ TTS_CASE_TPL("noalias behavior - dynamicallly sized", rotgen::tests::types)
|
||||||
rotgen::noalias(e) = a * a;
|
rotgen::noalias(e) = a * a;
|
||||||
TTS_EQUAL(c, ref);
|
TTS_EQUAL(c, ref);
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>> m(d.data(),2,2);
|
rotgen::map<rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>> m(
|
||||||
|
d.data(), 2, 2);
|
||||||
rotgen::noalias(m) = a * a;
|
rotgen::noalias(m) = a * a;
|
||||||
TTS_EQUAL(m, ref);
|
TTS_EQUAL(m, ref);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("noalias behavior - statically sized", rotgen::tests::types)
|
TTS_CASE_TPL("noalias behavior - statically sized",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, 2, 2, O::value> a{{1, 2}, {3, 4}};
|
rotgen::matrix<T, 2, 2, O::value> a{{1, 2}, {3, 4}};
|
||||||
rotgen::matrix<T, 2, 2, O::value> ref{{7, 10}, {15, 22}};
|
rotgen::matrix<T, 2, 2, O::value> ref{{7, 10}, {15, 22}};
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,9 @@
|
||||||
#include "unit/tests.hpp"
|
#include "unit/tests.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Chains of extraction", rotgen::tests::types)
|
TTS_CASE_TPL("Chains of extraction",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
constexpr int N = 8;
|
constexpr int N = 8;
|
||||||
auto a = rotgen::matrix<T, N, N, O::value>::Random();
|
auto a = rotgen::matrix<T, N, N, O::value>::Random();
|
||||||
|
|
@ -20,8 +21,7 @@ TTS_CASE_TPL("Chains of extraction", rotgen::tests::types)
|
||||||
setConstant(b, -7);
|
setConstant(b, -7);
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < 5; r++)
|
for (rotgen::Index r = 0; r < 5; r++)
|
||||||
for(rotgen::Index c=0;c<5;c++)
|
for (rotgen::Index c = 0; c < 5; c++) TTS_EQUAL(a(r, c), -7);
|
||||||
TTS_EQUAL(a(r,c), -7);
|
|
||||||
|
|
||||||
auto bb = bottomRightCorner(b, 3, 3);
|
auto bb = bottomRightCorner(b, 3, 3);
|
||||||
TTS_EQUAL(bb.startRow(), 2);
|
TTS_EQUAL(bb.startRow(), 2);
|
||||||
|
|
@ -29,16 +29,14 @@ TTS_CASE_TPL("Chains of extraction", rotgen::tests::types)
|
||||||
setConstant(bb, 42);
|
setConstant(bb, 42);
|
||||||
|
|
||||||
for (rotgen::Index r = 2; r < 5; r++)
|
for (rotgen::Index r = 2; r < 5; r++)
|
||||||
for(rotgen::Index c=2;c<5;c++)
|
for (rotgen::Index c = 2; c < 5; c++) TTS_EQUAL(a(r, c), 42);
|
||||||
TTS_EQUAL(a(r,c), 42);
|
|
||||||
|
|
||||||
auto bbb = row(bb, 1);
|
auto bbb = row(bb, 1);
|
||||||
TTS_EQUAL(bbb.startRow(), 1);
|
TTS_EQUAL(bbb.startRow(), 1);
|
||||||
TTS_EQUAL(bbb.startCol(), 0);
|
TTS_EQUAL(bbb.startCol(), 0);
|
||||||
setConstant(bbb, 99.5);
|
setConstant(bbb, 99.5);
|
||||||
|
|
||||||
for(rotgen::Index c=3;c<5;c++)
|
for (rotgen::Index c = 3; c < 5; c++) TTS_EQUAL(a(3, c), 99.5);
|
||||||
TTS_EQUAL(a(3,c), 99.5);
|
|
||||||
|
|
||||||
auto bbbb = col(bbb, 1);
|
auto bbbb = col(bbb, 1);
|
||||||
TTS_EQUAL(bbbb.startRow(), 0);
|
TTS_EQUAL(bbbb.startRow(), 0);
|
||||||
|
|
@ -48,8 +46,15 @@ TTS_CASE_TPL("Chains of extraction", rotgen::tests::types)
|
||||||
TTS_EQUAL(a(3, 3), 0.125);
|
TTS_EQUAL(a(3, 3), 0.125);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto ref_extract ( rotgen::ref<rotgen::matrix<float> > m) { return rotgen::extract(m,0,0,3,4); }
|
auto ref_extract(rotgen::ref<rotgen::matrix<float>> m)
|
||||||
auto ref_cextract( rotgen::ref<const rotgen::matrix<float> > m) { return rotgen::extract(m,3,4,4,3); }
|
{
|
||||||
|
return rotgen::extract(m, 0, 0, 3, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ref_cextract(rotgen::ref<rotgen::matrix<float> const> m)
|
||||||
|
{
|
||||||
|
return rotgen::extract(m, 3, 4, 4, 3);
|
||||||
|
}
|
||||||
|
|
||||||
TTS_CASE("Extraction of ref/ref const")
|
TTS_CASE("Extraction of ref/ref const")
|
||||||
{
|
{
|
||||||
|
|
@ -59,12 +64,11 @@ TTS_CASE("Extraction of ref/ref const")
|
||||||
extracted = rotgen::setOnes<rotgen::matrix<float, 3, 4>>();
|
extracted = rotgen::setOnes<rotgen::matrix<float, 3, 4>>();
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < 3; r++)
|
for (rotgen::Index r = 0; r < 3; r++)
|
||||||
for(rotgen::Index c=0;c<4;c++)
|
for (rotgen::Index c = 0; c < 4; c++) TTS_EQUAL(m(r, c), 1.f);
|
||||||
TTS_EQUAL(m(r,c), 1.f);
|
|
||||||
|
|
||||||
auto sliced = ref_cextract(m);
|
auto sliced = ref_cextract(m);
|
||||||
rotgen::extract(m,3,4,4,3) = rotgen::setConstant<rotgen::matrix<float,4,3>>(5);
|
rotgen::extract(m, 3, 4, 4, 3) =
|
||||||
|
rotgen::setConstant<rotgen::matrix<float, 4, 3>>(5);
|
||||||
for (rotgen::Index r = 0; r < 4; r++)
|
for (rotgen::Index r = 0; r < 4; r++)
|
||||||
for(rotgen::Index c=0;c<3;c++)
|
for (rotgen::Index c = 0; c < 3; c++) TTS_EQUAL(sliced(r, c), 5.f);
|
||||||
TTS_EQUAL(sliced(r,c), 5.f);
|
|
||||||
};
|
};
|
||||||
|
|
@ -9,20 +9,22 @@
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
TTS_CASE_TPL("I/O for matrix", rotgen::tests::types)
|
TTS_CASE_TPL("I/O for matrix", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> x({ {1,2} , {3,4} });
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> x(
|
||||||
|
{{1, 2}, {3, 4}});
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << x;
|
os << x;
|
||||||
|
|
||||||
TTS_EQUAL(os.str(), std::string{"1 2\n3 4"});
|
TTS_EQUAL(os.str(), std::string{"1 2\n3 4"});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("I/O for block", rotgen::tests::types)
|
TTS_CASE_TPL("I/O for block", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> base({ {1,2} , {3,4} });
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(
|
||||||
|
{{1, 2}, {3, 4}});
|
||||||
|
|
||||||
auto x = rotgen::extract(base, 0, 0, 2, 2);
|
auto x = rotgen::extract(base, 0, 0, 2, 2);
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
|
@ -31,8 +33,8 @@ TTS_CASE_TPL("I/O for block", rotgen::tests::types)
|
||||||
TTS_EQUAL(os.str(), std::string{"1 2\n3 4"});
|
TTS_EQUAL(os.str(), std::string{"1 2\n3 4"});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("I/O for map test", rotgen::tests::types)
|
TTS_CASE_TPL("I/O for map test", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using base = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using base = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
|
|
||||||
|
|
@ -46,12 +48,14 @@ TTS_CASE_TPL("I/O for map test", rotgen::tests::types)
|
||||||
else TTS_EQUAL(os.str(), std::string{"1 3\n2 4"});
|
else TTS_EQUAL(os.str(), std::string{"1 3\n2 4"});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("I/O using format", rotgen::tests::types)
|
TTS_CASE_TPL("I/O using format", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::ioformat io(rotgen::StreamPrecision, 0, ", ", ";\n", "<", ">", "[", "]");
|
rotgen::ioformat io(rotgen::StreamPrecision, 0, ", ", ";\n", "<", ">", "[",
|
||||||
|
"]");
|
||||||
|
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> x({ {1,2} , {3,4} });
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> x(
|
||||||
|
{{1, 2}, {3, 4}});
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
|
|
@ -73,8 +77,9 @@ TTS_CASE_TPL("I/O using format", rotgen::tests::types)
|
||||||
TTS_EQUAL(os.str(), std::string{"[<1, 2>;\n <3, 4>]"});
|
TTS_EQUAL(os.str(), std::string{"[<1, 2>;\n <3, 4>]"});
|
||||||
}
|
}
|
||||||
|
|
||||||
auto printer = [&](rotgen::ref<const rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>> r)
|
auto printer =
|
||||||
{
|
[&](rotgen::ref<rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic,
|
||||||
|
O::value> const> r) {
|
||||||
std::ostringstream st;
|
std::ostringstream st;
|
||||||
st << rotgen::format(r, io);
|
st << rotgen::format(r, io);
|
||||||
return st.str();
|
return st.str();
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,9 @@
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
TTS_CASE_TPL("outer_stride<0> interactions", rotgen::tests::types)
|
TTS_CASE_TPL("outer_stride<0> interactions",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
|
|
||||||
|
|
@ -27,7 +28,8 @@ TTS_CASE_TPL("outer_stride<0> interactions", rotgen::tests::types)
|
||||||
TTS_EQUAL(sp.innerStride(), 1);
|
TTS_EQUAL(sp.innerStride(), 1);
|
||||||
TTS_EQUAL(sp.outerStride(), 5);
|
TTS_EQUAL(sp.outerStride(), 5);
|
||||||
|
|
||||||
rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3,rotgen::outer_stride(5));
|
rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3,
|
||||||
|
rotgen::outer_stride(5));
|
||||||
TTS_EQUAL(dp.innerStride(), 1);
|
TTS_EQUAL(dp.innerStride(), 1);
|
||||||
TTS_EQUAL(dp.outerStride(), 5);
|
TTS_EQUAL(dp.outerStride(), 5);
|
||||||
|
|
||||||
|
|
@ -42,7 +44,8 @@ TTS_CASE_TPL("outer_stride<0> interactions", rotgen::tests::types)
|
||||||
TTS_EQUAL(sp.innerStride(), 1);
|
TTS_EQUAL(sp.innerStride(), 1);
|
||||||
TTS_EQUAL(sp.outerStride(), 4);
|
TTS_EQUAL(sp.outerStride(), 4);
|
||||||
|
|
||||||
rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3,rotgen::outer_stride(4));
|
rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3,
|
||||||
|
rotgen::outer_stride(4));
|
||||||
TTS_EQUAL(dp.innerStride(), 1);
|
TTS_EQUAL(dp.innerStride(), 1);
|
||||||
TTS_EQUAL(dp.outerStride(), 4);
|
TTS_EQUAL(dp.outerStride(), 4);
|
||||||
|
|
||||||
|
|
@ -52,13 +55,27 @@ TTS_CASE_TPL("outer_stride<0> interactions", rotgen::tests::types)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void process_ref(rotgen::ref<const rotgen::matrix<float>> ) {}
|
void process_ref(rotgen::ref<rotgen::matrix<float> const>) {}
|
||||||
void process_ref(rotgen::ref<const rotgen::matrix<double>>) {}
|
|
||||||
void process_ref(rotgen::ref<const rotgen::matrix<float , rotgen::Dynamic, rotgen::Dynamic, rotgen::RowMajor>>) {}
|
|
||||||
void process_ref(rotgen::ref<const rotgen::matrix<double, rotgen::Dynamic, rotgen::Dynamic, rotgen::RowMajor>>) {}
|
|
||||||
|
|
||||||
TTS_CASE_TPL("Extraction of outer_stride<?> blocks", rotgen::tests::types)
|
void process_ref(rotgen::ref<rotgen::matrix<double> const>) {}
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
|
||||||
|
void process_ref(
|
||||||
|
rotgen::ref<
|
||||||
|
rotgen::
|
||||||
|
matrix<float, rotgen::Dynamic, rotgen::Dynamic, rotgen::RowMajor> const>)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_ref(
|
||||||
|
rotgen::ref<
|
||||||
|
rotgen::
|
||||||
|
matrix<double, rotgen::Dynamic, rotgen::Dynamic, rotgen::RowMajor> const>)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TTS_CASE_TPL("Extraction of outer_stride<?> blocks",
|
||||||
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
|
|
||||||
|
|
@ -66,7 +83,8 @@ TTS_CASE_TPL("Extraction of outer_stride<?> blocks", rotgen::tests::types)
|
||||||
{
|
{
|
||||||
T padded[] = {1, 2, 3, 4, 99, 5, 6, 7, 8, 99, 9, 10, 11, 12};
|
T padded[] = {1, 2, 3, 4, 99, 5, 6, 7, 8, 99, 9, 10, 11, 12};
|
||||||
rotgen::map<mat_t, 0, rotgen::outer_stride<5>> sp(&padded[0], 4, 3);
|
rotgen::map<mat_t, 0, rotgen::outer_stride<5>> sp(&padded[0], 4, 3);
|
||||||
rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3,rotgen::outer_stride(5));
|
rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3,
|
||||||
|
rotgen::outer_stride(5));
|
||||||
|
|
||||||
TTS_EXPECT_COMPILES(sp, { process_ref(extract(sp, 0, 0, 3, 2)); });
|
TTS_EXPECT_COMPILES(sp, { process_ref(extract(sp, 0, 0, 3, 2)); });
|
||||||
TTS_EXPECT_COMPILES(dp, { process_ref(extract(dp, 0, 0, 3, 2)); });
|
TTS_EXPECT_COMPILES(dp, { process_ref(extract(dp, 0, 0, 3, 2)); });
|
||||||
|
|
@ -75,7 +93,8 @@ TTS_CASE_TPL("Extraction of outer_stride<?> blocks", rotgen::tests::types)
|
||||||
{
|
{
|
||||||
T padded[] = {1, 2, 3, 99, 4, 5, 6, 99, 7, 8, 9, 99, 10, 11, 12};
|
T padded[] = {1, 2, 3, 99, 4, 5, 6, 99, 7, 8, 9, 99, 10, 11, 12};
|
||||||
rotgen::map<mat_t, 0, rotgen::outer_stride<4>> sp(&padded[0], 4, 3);
|
rotgen::map<mat_t, 0, rotgen::outer_stride<4>> sp(&padded[0], 4, 3);
|
||||||
rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3,rotgen::outer_stride(4));
|
rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3,
|
||||||
|
rotgen::outer_stride(4));
|
||||||
|
|
||||||
TTS_EXPECT_COMPILES(sp, { process_ref(extract(sp, 0, 0, 3, 2)); });
|
TTS_EXPECT_COMPILES(sp, { process_ref(extract(sp, 0, 0, 3, 2)); });
|
||||||
TTS_EXPECT_COMPILES(dp, { process_ref(extract(dp, 0, 0, 3, 2)); });
|
TTS_EXPECT_COMPILES(dp, { process_ref(extract(dp, 0, 0, 3, 2)); });
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,9 @@
|
||||||
#include "unit/tests.hpp"
|
#include "unit/tests.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
template<int size = rotgen::Dynamic, typename Scalar = float, int maxSize = size>
|
template<int size = rotgen::Dynamic,
|
||||||
|
typename Scalar = float,
|
||||||
|
int maxSize = size>
|
||||||
using column = rotgen::matrix<Scalar, size, 1, rotgen::ColMajor, maxSize, 1>;
|
using column = rotgen::matrix<Scalar, size, 1, rotgen::ColMajor, maxSize, 1>;
|
||||||
|
|
||||||
template<int size = rotgen::Dynamic, typename Scalar = float>
|
template<int size = rotgen::Dynamic, typename Scalar = float>
|
||||||
|
|
@ -17,9 +19,7 @@ using column_ref = rotgen::ref<column<size, Scalar>>;
|
||||||
template<int size = rotgen::Dynamic, typename Scalar = float>
|
template<int size = rotgen::Dynamic, typename Scalar = float>
|
||||||
using const_column_ref = rotgen::ref<column<size, Scalar> const>;
|
using const_column_ref = rotgen::ref<column<size, Scalar> const>;
|
||||||
|
|
||||||
|
template<int N> void process(column_ref<N> v)
|
||||||
template<int N>
|
|
||||||
void process( column_ref<N> v )
|
|
||||||
{
|
{
|
||||||
v(0) = rotgen::sum(v);
|
v(0) = rotgen::sum(v);
|
||||||
}
|
}
|
||||||
|
|
@ -29,10 +29,17 @@ auto process( column_ref<> v )
|
||||||
auto sz = v.size();
|
auto sz = v.size();
|
||||||
switch (sz)
|
switch (sz)
|
||||||
{
|
{
|
||||||
case 1 : process<1>(v); break;
|
case 1:
|
||||||
case 2 : process<2>(v); break;
|
process<1>(v);
|
||||||
case 3 : process<3>(v); break;
|
break;
|
||||||
default: break;
|
case 2:
|
||||||
|
process<2>(v);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
process<3>(v);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sz;
|
return sz;
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,12 @@
|
||||||
#include "unit/common/arithmetic.hpp"
|
#include "unit/common/arithmetic.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic block transposition-like operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic block transposition-like operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
||||||
for (const auto& [matrix_desc, i0, j0, ni, nj] : cases)
|
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
|
||||||
{
|
{
|
||||||
auto [rows, cols, fn] = matrix_desc;
|
auto [rows, cols, fn] = matrix_desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
@ -23,13 +24,13 @@ TTS_CASE_TPL("Test dynamic block transposition-like operations", rotgen::tests::
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static block transposition-like operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test static block transposition-like operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& d)
|
auto process = []<typename D>(D const& d) {
|
||||||
{
|
|
||||||
auto [desc, i0, j0] = d;
|
auto [desc, i0, j0] = d;
|
||||||
auto [rows, cols, fn] = desc;
|
auto [rows, cols, fn] = desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
@ -41,11 +42,12 @@ TTS_CASE_TPL("Test static block transposition-like operations", rotgen::tests::t
|
||||||
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic block reduction-like operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic block reduction-like operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
||||||
for (const auto& [matrix_desc, i0, j0, ni, nj] : cases)
|
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
|
||||||
{
|
{
|
||||||
auto [rows, cols, fn] = matrix_desc;
|
auto [rows, cols, fn] = matrix_desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
@ -55,13 +57,13 @@ TTS_CASE_TPL("Test dynamic block reduction-like operations", rotgen::tests::type
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static block reduction-like operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test static block reduction-like operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& d)
|
auto process = []<typename D>(D const& d) {
|
||||||
{
|
|
||||||
auto [desc, i0, j0] = d;
|
auto [desc, i0, j0] = d;
|
||||||
auto [rows, cols, fn] = desc;
|
auto [rows, cols, fn] = desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
@ -73,13 +75,10 @@ TTS_CASE_TPL("Test static block reduction-like operations", rotgen::tests::types
|
||||||
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TTS_CASE_TPL("Test dot product", float, double)<typename T>(tts::type<T>){
|
||||||
|
{auto v = rotgen::setConstant<rotgen::matrix<T, 1, rotgen::Dynamic>>(1,
|
||||||
TTS_CASE_TPL("Test dot product", float, double)
|
16,
|
||||||
<typename T>( tts::type<T> )
|
2);
|
||||||
{
|
|
||||||
{
|
|
||||||
auto v = rotgen::setConstant<rotgen::matrix<T,1,rotgen::Dynamic>>(1,16,2);
|
|
||||||
auto a = rotgen::head(v, 8);
|
auto a = rotgen::head(v, 8);
|
||||||
auto b = rotgen::tail(v, 8);
|
auto b = rotgen::tail(v, 8);
|
||||||
|
|
||||||
|
|
@ -109,4 +108,5 @@ TTS_CASE_TPL("Test dot product", float, double)
|
||||||
|
|
||||||
TTS_EQUAL(rotgen::dot(a, b), 32);
|
TTS_EQUAL(rotgen::dot(a, b), 32);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
;
|
||||||
|
|
|
||||||
|
|
@ -12,32 +12,35 @@
|
||||||
// NB: This function must not be turned into a lambda, otherwise
|
// NB: This function must not be turned into a lambda, otherwise
|
||||||
// `test-ubuntu-gcc-release` will not pass and the CI will fail.
|
// `test-ubuntu-gcc-release` will not pass and the CI will fail.
|
||||||
// This is likely due to a compilation bug from GCC 13.3.0.
|
// This is likely due to a compilation bug from GCC 13.3.0.
|
||||||
void fill(auto &m, int r, int c, auto data[]) {
|
void fill(auto& m, int r, int c, auto data[])
|
||||||
for (int k = 0; k < r * c; ++k)
|
{
|
||||||
m.data()[k] = data[k];
|
for (int k = 0; k < r * c; ++k) m.data()[k] = data[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
TTS_CASE_TPL("Function size", rotgen::tests::types)
|
TTS_CASE_TPL("Function size", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||||
|
|
||||||
// 1x12 dynamic block at (0,0)
|
// 1x12 dynamic block at (0,0)
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> dm(1, 12);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> dm(1, 12);
|
||||||
fill(dm, 1, 12, data);
|
fill(dm, 1, 12, data);
|
||||||
auto b1 = rotgen::block<decltype(dm), rotgen::Dynamic, rotgen::Dynamic>(dm, 0,0,1,12);
|
auto b1 = rotgen::block<decltype(dm), rotgen::Dynamic, rotgen::Dynamic>(
|
||||||
|
dm, 0, 0, 1, 12);
|
||||||
TTS_EQUAL(b1.rows(), rotgen::Index{1});
|
TTS_EQUAL(b1.rows(), rotgen::Index{1});
|
||||||
TTS_EQUAL(b1.cols(), rotgen::Index{12});
|
TTS_EQUAL(b1.cols(), rotgen::Index{12});
|
||||||
|
|
||||||
// 1x5 dynamic block at (0,2)
|
// 1x5 dynamic block at (0,2)
|
||||||
auto b2 = rotgen::block<decltype(dm), rotgen::Dynamic, rotgen::Dynamic>(dm, 0,2,1,5);
|
auto b2 = rotgen::block<decltype(dm), rotgen::Dynamic, rotgen::Dynamic>(
|
||||||
|
dm, 0, 2, 1, 5);
|
||||||
TTS_EQUAL(b2.rows(), rotgen::Index{1});
|
TTS_EQUAL(b2.rows(), rotgen::Index{1});
|
||||||
TTS_EQUAL(b2.cols(), rotgen::Index{5});
|
TTS_EQUAL(b2.cols(), rotgen::Index{5});
|
||||||
|
|
||||||
// 3x2 dynamic block at (1,4) in 4x6
|
// 3x2 dynamic block at (1,4) in 4x6
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> dm2(4, 6);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> dm2(4, 6);
|
||||||
fill(dm2, 4, 6, data);
|
fill(dm2, 4, 6, data);
|
||||||
auto b3 = rotgen::block<decltype(dm2), rotgen::Dynamic, rotgen::Dynamic>(dm2, 1,4,3,2);
|
auto b3 = rotgen::block<decltype(dm2), rotgen::Dynamic, rotgen::Dynamic>(
|
||||||
|
dm2, 1, 4, 3, 2);
|
||||||
TTS_EQUAL(b3.rows(), rotgen::Index{3});
|
TTS_EQUAL(b3.rows(), rotgen::Index{3});
|
||||||
TTS_EQUAL(b3.cols(), rotgen::Index{2});
|
TTS_EQUAL(b3.cols(), rotgen::Index{2});
|
||||||
TTS_EQUAL(b3.size(), rotgen::Index{6});
|
TTS_EQUAL(b3.size(), rotgen::Index{6});
|
||||||
|
|
@ -59,8 +62,9 @@ TTS_CASE_TPL("Function size", rotgen::tests::types)
|
||||||
TTS_EQUAL(b5.size(), rotgen::Index{12});
|
TTS_EQUAL(b5.size(), rotgen::Index{12});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
|
TTS_CASE_TPL("Test coefficient accessors",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using base = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using base = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
|
|
||||||
|
|
@ -68,7 +72,8 @@ TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
|
||||||
base mat(4, 3);
|
base mat(4, 3);
|
||||||
for (int k = 0; k < 12; ++k) mat.data()[k] = data[k];
|
for (int k = 0; k < 12; ++k) mat.data()[k] = data[k];
|
||||||
|
|
||||||
auto b = rotgen::block<base,rotgen::Dynamic,rotgen::Dynamic>(mat, 0, 0, 4, 3);
|
auto b =
|
||||||
|
rotgen::block<base, rotgen::Dynamic, rotgen::Dynamic>(mat, 0, 0, 4, 3);
|
||||||
for (rotgen::Index i = 0; i < 4; i++)
|
for (rotgen::Index i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
for (rotgen::Index j = 0; j < 3; j++)
|
for (rotgen::Index j = 0; j < 3; j++)
|
||||||
|
|
@ -86,24 +91,26 @@ TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
|
||||||
TTS_EQUAL(b(2, 2), 17);
|
TTS_EQUAL(b(2, 2), 17);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types)
|
TTS_CASE_TPL("Test one index coefficient accessors",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
{
|
tts::type<tts::types<T, O>>)
|
||||||
auto vs = [&]()
|
|
||||||
{
|
{
|
||||||
|
auto vs = [&]() {
|
||||||
if constexpr (O::value == rotgen::ColMajor)
|
if constexpr (O::value == rotgen::ColMajor)
|
||||||
{
|
{
|
||||||
using base = rotgen::matrix<T, 1, rotgen::Dynamic>;
|
using base = rotgen::matrix<T, 1, rotgen::Dynamic>;
|
||||||
base m(12);
|
base m(12);
|
||||||
for (int k = 0; k < 12; ++k) m(k) = k + 1;
|
for (int k = 0; k < 12; ++k) m(k) = k + 1;
|
||||||
return std::tuple{m,rotgen::block<base,1,rotgen::Dynamic>(m, 0, 0, 1, 12)};
|
return std::tuple{
|
||||||
|
m, rotgen::block<base, 1, rotgen::Dynamic>(m, 0, 0, 1, 12)};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using base = rotgen::matrix<T, rotgen::Dynamic, 1>;
|
using base = rotgen::matrix<T, rotgen::Dynamic, 1>;
|
||||||
base m(12);
|
base m(12);
|
||||||
for (int k = 0; k < 12; ++k) m(k) = k + 1;
|
for (int k = 0; k < 12; ++k) m(k) = k + 1;
|
||||||
return std::tuple{m,rotgen::block<base,rotgen::Dynamic,1>(m, 0, 0, 12, 1)};
|
return std::tuple{
|
||||||
|
m, rotgen::block<base, rotgen::Dynamic, 1>(m, 0, 0, 12, 1)};
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,12 @@
|
||||||
#include "unit/common/cwise.hpp"
|
#include "unit/common/cwise.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic block cwise operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic block cwise operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
||||||
for (const auto& [matrix_desc, i0, j0, ni, nj] : cases)
|
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
|
||||||
{
|
{
|
||||||
auto [rows, cols, fn] = matrix_desc;
|
auto [rows, cols, fn] = matrix_desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
@ -23,13 +24,13 @@ TTS_CASE_TPL("Test dynamic block cwise operations", rotgen::tests::types)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static block cwise operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test static block cwise operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& d)
|
auto process = []<typename D>(D const& d) {
|
||||||
{
|
|
||||||
auto [desc, i0, j0] = d;
|
auto [desc, i0, j0] = d;
|
||||||
auto [rows, cols, fn] = desc;
|
auto [rows, cols, fn] = desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
|
||||||
|
|
@ -12,27 +12,27 @@ template<typename EigenType, typename F>
|
||||||
void for_each_element(EigenType const& m, F&& f)
|
void for_each_element(EigenType const& m, F&& f)
|
||||||
{
|
{
|
||||||
for (rotgen::Index i = 0; i < m.rows(); ++i)
|
for (rotgen::Index i = 0; i < m.rows(); ++i)
|
||||||
for(rotgen::Index j = 0; j < m.cols(); ++j)
|
for (rotgen::Index j = 0; j < m.cols(); ++j) f(i, j, m(i, j));
|
||||||
f(i, j, m(i,j));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename EigenType, typename F>
|
template<typename EigenType, typename F>
|
||||||
void for_each_element(EigenType& m, F&& f)
|
void for_each_element(EigenType& m, F&& f)
|
||||||
{
|
{
|
||||||
for (rotgen::Index i = 0; i < m.rows(); ++i)
|
for (rotgen::Index i = 0; i < m.rows(); ++i)
|
||||||
for(rotgen::Index j = 0; j < m.cols(); ++j)
|
for (rotgen::Index j = 0; j < m.cols(); ++j) f(i, j, m(i, j));
|
||||||
f(i, j, m(i,j));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType, typename T>
|
template<typename MatrixType, typename T>
|
||||||
MatrixType make_initialized_matrix(rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct)
|
MatrixType make_initialized_matrix(
|
||||||
|
rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct)
|
||||||
{
|
{
|
||||||
auto [d, i0, j0, ni, nj] = matrix_construct;
|
auto [d, i0, j0, ni, nj] = matrix_construct;
|
||||||
auto [r, c, fn] = d;
|
auto [r, c, fn] = d;
|
||||||
|
|
||||||
MatrixType matrix;
|
MatrixType matrix;
|
||||||
|
|
||||||
if constexpr(MatrixType::RowsAtCompileTime == -1 &&MatrixType::ColsAtCompileTime == -1)
|
if constexpr (MatrixType::RowsAtCompileTime == -1 &&
|
||||||
|
MatrixType::ColsAtCompileTime == -1)
|
||||||
rotgen::resize(matrix, r, c);
|
rotgen::resize(matrix, r, c);
|
||||||
|
|
||||||
for (rotgen::Index i = 0; i < r; ++i)
|
for (rotgen::Index i = 0; i < r; ++i)
|
||||||
|
|
@ -43,9 +43,12 @@ MatrixType make_initialized_matrix(rotgen::tests::matrix_block_test_case<MatrixT
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType, typename BlockType>
|
template<typename MatrixType, typename BlockType>
|
||||||
void validate_block_behavior(MatrixType& matrix, BlockType& block,
|
void validate_block_behavior(MatrixType& matrix,
|
||||||
rotgen::Index block_i, rotgen::Index block_j,
|
BlockType& block,
|
||||||
rotgen::Index block_m, rotgen::Index block_n)
|
rotgen::Index block_i,
|
||||||
|
rotgen::Index block_j,
|
||||||
|
rotgen::Index block_m,
|
||||||
|
rotgen::Index block_n)
|
||||||
{
|
{
|
||||||
using T = typename MatrixType::value_type;
|
using T = typename MatrixType::value_type;
|
||||||
TTS_EQUAL(block.rows(), block_m);
|
TTS_EQUAL(block.rows(), block_m);
|
||||||
|
|
@ -61,9 +64,8 @@ void validate_block_behavior(MatrixType& matrix, BlockType& block,
|
||||||
if constexpr (!BlockType::is_immutable)
|
if constexpr (!BlockType::is_immutable)
|
||||||
{
|
{
|
||||||
T value = 1;
|
T value = 1;
|
||||||
for_each_element(block, [&](auto i, auto j, auto&) {
|
for_each_element(block,
|
||||||
block(i, j) = value++;
|
[&](auto i, auto j, auto&) { block(i, j) = value++; });
|
||||||
});
|
|
||||||
|
|
||||||
value = 1;
|
value = 1;
|
||||||
for_each_element(block, [&](auto i, auto j, auto&) {
|
for_each_element(block, [&](auto i, auto j, auto&) {
|
||||||
|
|
@ -81,79 +83,117 @@ void validate_block_behavior(MatrixType& matrix, BlockType& block,
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType, typename T>
|
template<typename MatrixType, typename T>
|
||||||
void test_dynamic_block_extraction(rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct)
|
void test_dynamic_block_extraction(
|
||||||
|
rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct)
|
||||||
{
|
{
|
||||||
MatrixType matrix = make_initialized_matrix<MatrixType, T>(matrix_construct);
|
MatrixType matrix = make_initialized_matrix<MatrixType, T>(matrix_construct);
|
||||||
|
|
||||||
MatrixType const c_matrix = matrix;
|
MatrixType const c_matrix = matrix;
|
||||||
|
|
||||||
auto c_block_main = rotgen::extract(c_matrix, matrix_construct.i0, matrix_construct.j0,
|
auto c_block_main =
|
||||||
|
rotgen::extract(c_matrix, matrix_construct.i0, matrix_construct.j0,
|
||||||
matrix_construct.ni, matrix_construct.nj);
|
matrix_construct.ni, matrix_construct.nj);
|
||||||
auto c_block_top_left_corner = rotgen::topLeftCorner(c_matrix, matrix_construct.ni, matrix_construct.nj);
|
auto c_block_top_left_corner =
|
||||||
auto c_block_top_right_corner = rotgen::topRightCorner(c_matrix, matrix_construct.ni, matrix_construct.nj);
|
rotgen::topLeftCorner(c_matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
auto c_block_bottom_left_corner = rotgen::bottomLeftCorner(c_matrix, matrix_construct.ni, matrix_construct.nj);
|
auto c_block_top_right_corner =
|
||||||
auto c_block_bottom_right_corner = rotgen::bottomRightCorner(c_matrix, matrix_construct.ni, matrix_construct.nj);
|
rotgen::topRightCorner(c_matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
|
auto c_block_bottom_left_corner = rotgen::bottomLeftCorner(
|
||||||
|
c_matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
|
auto c_block_bottom_right_corner = rotgen::bottomRightCorner(
|
||||||
|
c_matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
|
|
||||||
auto c_block_top_rows = rotgen::topRows(c_matrix, matrix_construct.ni);
|
auto c_block_top_rows = rotgen::topRows(c_matrix, matrix_construct.ni);
|
||||||
auto c_block_middle_rows = rotgen::middleRows(c_matrix, matrix_construct.i0, matrix_construct.ni);
|
auto c_block_middle_rows =
|
||||||
|
rotgen::middleRows(c_matrix, matrix_construct.i0, matrix_construct.ni);
|
||||||
auto c_block_bottom_rows = rotgen::bottomRows(c_matrix, matrix_construct.ni);
|
auto c_block_bottom_rows = rotgen::bottomRows(c_matrix, matrix_construct.ni);
|
||||||
|
|
||||||
auto c_block_left_cols = rotgen::leftCols(c_matrix, matrix_construct.nj);
|
auto c_block_left_cols = rotgen::leftCols(c_matrix, matrix_construct.nj);
|
||||||
auto c_block_middle_cols = rotgen::middleCols(c_matrix, matrix_construct.j0, matrix_construct.nj);
|
auto c_block_middle_cols =
|
||||||
|
rotgen::middleCols(c_matrix, matrix_construct.j0, matrix_construct.nj);
|
||||||
auto c_block_right_cols = rotgen::rightCols(c_matrix, matrix_construct.nj);
|
auto c_block_right_cols = rotgen::rightCols(c_matrix, matrix_construct.nj);
|
||||||
|
|
||||||
auto block_main = rotgen::extract(matrix, matrix_construct.i0, matrix_construct.j0,
|
auto block_main =
|
||||||
|
rotgen::extract(matrix, matrix_construct.i0, matrix_construct.j0,
|
||||||
matrix_construct.ni, matrix_construct.nj);
|
matrix_construct.ni, matrix_construct.nj);
|
||||||
auto block_top_left_corner = rotgen::topLeftCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
auto block_top_left_corner =
|
||||||
auto block_top_right_corner = rotgen::topRightCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
rotgen::topLeftCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
auto block_bottom_left_corner = rotgen::bottomLeftCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
auto block_top_right_corner =
|
||||||
auto block_bottom_right_corner = rotgen::bottomRightCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
rotgen::topRightCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
|
auto block_bottom_left_corner =
|
||||||
|
rotgen::bottomLeftCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
|
auto block_bottom_right_corner =
|
||||||
|
rotgen::bottomRightCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
|
|
||||||
auto block_top_rows = rotgen::topRows(matrix, matrix_construct.ni);
|
auto block_top_rows = rotgen::topRows(matrix, matrix_construct.ni);
|
||||||
auto block_middle_rows = rotgen::middleRows(matrix, matrix_construct.i0, matrix_construct.ni);
|
auto block_middle_rows =
|
||||||
|
rotgen::middleRows(matrix, matrix_construct.i0, matrix_construct.ni);
|
||||||
auto block_bottom_rows = rotgen::bottomRows(matrix, matrix_construct.ni);
|
auto block_bottom_rows = rotgen::bottomRows(matrix, matrix_construct.ni);
|
||||||
|
|
||||||
auto block_left_cols = rotgen::leftCols(matrix, matrix_construct.nj);
|
auto block_left_cols = rotgen::leftCols(matrix, matrix_construct.nj);
|
||||||
auto block_middle_cols = rotgen::middleCols(matrix, matrix_construct.j0, matrix_construct.nj);
|
auto block_middle_cols =
|
||||||
|
rotgen::middleCols(matrix, matrix_construct.j0, matrix_construct.nj);
|
||||||
auto block_right_cols = rotgen::rightCols(matrix, matrix_construct.nj);
|
auto block_right_cols = rotgen::rightCols(matrix, matrix_construct.nj);
|
||||||
|
|
||||||
auto blocks = std::make_tuple(
|
auto blocks = std::make_tuple(
|
||||||
// --- CONST TESTS
|
// --- CONST TESTS
|
||||||
std::make_tuple(c_block_main, matrix_construct.i0, matrix_construct.j0, matrix_construct.ni, matrix_construct.nj),
|
std::make_tuple(c_block_main, matrix_construct.i0, matrix_construct.j0,
|
||||||
std::make_tuple(c_block_top_left_corner, 0, 0, matrix_construct.ni, matrix_construct.nj),
|
|
||||||
std::make_tuple(c_block_top_right_corner, 0, matrix.cols() - matrix_construct.nj, matrix_construct.ni, matrix_construct.nj),
|
|
||||||
std::make_tuple(c_block_bottom_left_corner, matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni, matrix_construct.nj),
|
|
||||||
std::make_tuple(c_block_bottom_right_corner, matrix.rows() - matrix_construct.ni, matrix.cols() - matrix_construct.nj,
|
|
||||||
matrix_construct.ni, matrix_construct.nj),
|
matrix_construct.ni, matrix_construct.nj),
|
||||||
|
std::make_tuple(c_block_top_left_corner, 0, 0, matrix_construct.ni,
|
||||||
|
matrix_construct.nj),
|
||||||
|
std::make_tuple(c_block_top_right_corner, 0,
|
||||||
|
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||||
|
matrix_construct.nj),
|
||||||
|
std::make_tuple(c_block_bottom_left_corner,
|
||||||
|
matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni,
|
||||||
|
matrix_construct.nj),
|
||||||
|
std::make_tuple(c_block_bottom_right_corner,
|
||||||
|
matrix.rows() - matrix_construct.ni,
|
||||||
|
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||||
|
matrix_construct.nj),
|
||||||
|
|
||||||
std::make_tuple(c_block_top_rows, 0, 0, matrix_construct.ni, matrix.cols()),
|
std::make_tuple(c_block_top_rows, 0, 0, matrix_construct.ni, matrix.cols()),
|
||||||
std::make_tuple(c_block_middle_rows, matrix_construct.i0, 0, matrix_construct.ni, matrix.cols()),
|
std::make_tuple(c_block_middle_rows, matrix_construct.i0, 0,
|
||||||
std::make_tuple(c_block_bottom_rows, matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni, matrix.cols()),
|
matrix_construct.ni, matrix.cols()),
|
||||||
|
std::make_tuple(c_block_bottom_rows, matrix.rows() - matrix_construct.ni, 0,
|
||||||
|
matrix_construct.ni, matrix.cols()),
|
||||||
|
|
||||||
std::make_tuple(c_block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj),
|
std::make_tuple(c_block_left_cols, 0, 0, matrix.rows(),
|
||||||
std::make_tuple(c_block_middle_cols, 0, matrix_construct.j0, matrix.rows(), matrix_construct.nj),
|
matrix_construct.nj),
|
||||||
std::make_tuple(c_block_right_cols, 0, matrix.cols() - matrix_construct.nj, matrix.rows(), matrix_construct.nj),
|
std::make_tuple(c_block_middle_cols, 0, matrix_construct.j0, matrix.rows(),
|
||||||
|
matrix_construct.nj),
|
||||||
|
std::make_tuple(c_block_right_cols, 0, matrix.cols() - matrix_construct.nj,
|
||||||
|
matrix.rows(), matrix_construct.nj),
|
||||||
// --- REGULAR TESTS
|
// --- REGULAR TESTS
|
||||||
std::make_tuple(block_main, matrix_construct.i0, matrix_construct.j0, matrix_construct.ni, matrix_construct.nj),
|
std::make_tuple(block_main, matrix_construct.i0, matrix_construct.j0,
|
||||||
std::make_tuple(block_top_left_corner, 0, 0, matrix_construct.ni, matrix_construct.nj),
|
|
||||||
std::make_tuple(block_top_right_corner, 0, matrix.cols() - matrix_construct.nj, matrix_construct.ni, matrix_construct.nj),
|
|
||||||
std::make_tuple(block_bottom_left_corner, matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni, matrix_construct.nj),
|
|
||||||
std::make_tuple(block_bottom_right_corner, matrix.rows() - matrix_construct.ni, matrix.cols() - matrix_construct.nj,
|
|
||||||
matrix_construct.ni, matrix_construct.nj),
|
matrix_construct.ni, matrix_construct.nj),
|
||||||
|
std::make_tuple(block_top_left_corner, 0, 0, matrix_construct.ni,
|
||||||
|
matrix_construct.nj),
|
||||||
|
std::make_tuple(block_top_right_corner, 0,
|
||||||
|
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||||
|
matrix_construct.nj),
|
||||||
|
std::make_tuple(block_bottom_left_corner,
|
||||||
|
matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni,
|
||||||
|
matrix_construct.nj),
|
||||||
|
std::make_tuple(block_bottom_right_corner,
|
||||||
|
matrix.rows() - matrix_construct.ni,
|
||||||
|
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||||
|
matrix_construct.nj),
|
||||||
|
|
||||||
std::make_tuple(block_top_rows, 0, 0, matrix_construct.ni, matrix.cols()),
|
std::make_tuple(block_top_rows, 0, 0, matrix_construct.ni, matrix.cols()),
|
||||||
std::make_tuple(block_middle_rows, matrix_construct.i0, 0, matrix_construct.ni, matrix.cols()),
|
std::make_tuple(block_middle_rows, matrix_construct.i0, 0,
|
||||||
std::make_tuple(block_bottom_rows, matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni, matrix.cols()),
|
matrix_construct.ni, matrix.cols()),
|
||||||
|
std::make_tuple(block_bottom_rows, matrix.rows() - matrix_construct.ni, 0,
|
||||||
|
matrix_construct.ni, matrix.cols()),
|
||||||
|
|
||||||
std::make_tuple(block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj),
|
std::make_tuple(block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj),
|
||||||
std::make_tuple(block_middle_cols, 0, matrix_construct.j0, matrix.rows(), matrix_construct.nj),
|
std::make_tuple(block_middle_cols, 0, matrix_construct.j0, matrix.rows(),
|
||||||
std::make_tuple(block_right_cols, 0, matrix.cols() - matrix_construct.nj, matrix.rows(), matrix_construct.nj)
|
matrix_construct.nj),
|
||||||
);
|
std::make_tuple(block_right_cols, 0, matrix.cols() - matrix_construct.nj,
|
||||||
|
matrix.rows(), matrix_construct.nj));
|
||||||
|
|
||||||
std::apply([&](auto&&... block_entries)
|
std::apply(
|
||||||
{
|
[&](auto&&... block_entries) {
|
||||||
(([&]
|
(([&] {
|
||||||
{
|
|
||||||
auto&& [block, i_offset, j_offset, ni, nj] = block_entries;
|
auto&& [block, i_offset, j_offset, ni, nj] = block_entries;
|
||||||
using block_t = std::remove_reference_t<decltype(block)>;
|
using block_t = std::remove_reference_t<decltype(block)>;
|
||||||
|
|
||||||
|
|
@ -162,13 +202,16 @@ void test_dynamic_block_extraction(rotgen::tests::matrix_block_test_case<MatrixT
|
||||||
TTS_EQUAL(block_t::storage_order, MatrixType::storage_order);
|
TTS_EQUAL(block_t::storage_order, MatrixType::storage_order);
|
||||||
|
|
||||||
validate_block_behavior(matrix, block, i_offset, j_offset, ni, nj);
|
validate_block_behavior(matrix, block, i_offset, j_offset, ni, nj);
|
||||||
})(), ...);
|
})(),
|
||||||
}, blocks);
|
...);
|
||||||
|
},
|
||||||
|
blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType, typename T, rotgen::Index NI, rotgen::Index NJ>
|
template<typename MatrixType, typename T, rotgen::Index NI, rotgen::Index NJ>
|
||||||
void test_static_block_extraction(rotgen::tests::static_matrix_block_test_case<MatrixType, NI, NJ> const& matrix_construct)
|
void test_static_block_extraction(
|
||||||
|
rotgen::tests::static_matrix_block_test_case<MatrixType, NI, NJ> const&
|
||||||
|
matrix_construct)
|
||||||
{
|
{
|
||||||
auto [d, i0, j0] = matrix_construct;
|
auto [d, i0, j0] = matrix_construct;
|
||||||
auto [r, c, fn] = d;
|
auto [r, c, fn] = d;
|
||||||
|
|
@ -185,7 +228,8 @@ void test_static_block_extraction(rotgen::tests::static_matrix_block_test_case<M
|
||||||
auto c_block_top_left_corner = rotgen::topLeftCorner<NI, NJ>(c_matrix);
|
auto c_block_top_left_corner = rotgen::topLeftCorner<NI, NJ>(c_matrix);
|
||||||
auto c_block_top_right_corner = rotgen::topRightCorner<NI, NJ>(c_matrix);
|
auto c_block_top_right_corner = rotgen::topRightCorner<NI, NJ>(c_matrix);
|
||||||
auto c_block_bottom_left_corner = rotgen::bottomLeftCorner<NI, NJ>(c_matrix);
|
auto c_block_bottom_left_corner = rotgen::bottomLeftCorner<NI, NJ>(c_matrix);
|
||||||
auto c_block_bottom_right_corner = rotgen::bottomRightCorner<NI, NJ>(c_matrix);
|
auto c_block_bottom_right_corner =
|
||||||
|
rotgen::bottomRightCorner<NI, NJ>(c_matrix);
|
||||||
auto c_block_top_rows = rotgen::topRows<NI>(c_matrix);
|
auto c_block_top_rows = rotgen::topRows<NI>(c_matrix);
|
||||||
auto c_block_middle_rows = rotgen::middleRows<NI>(c_matrix, i0);
|
auto c_block_middle_rows = rotgen::middleRows<NI>(c_matrix, i0);
|
||||||
auto c_block_bottom_rows = rotgen::bottomRows<NI>(c_matrix);
|
auto c_block_bottom_rows = rotgen::bottomRows<NI>(c_matrix);
|
||||||
|
|
@ -212,144 +256,185 @@ void test_static_block_extraction(rotgen::tests::static_matrix_block_test_case<M
|
||||||
auto blocks = std::make_tuple(
|
auto blocks = std::make_tuple(
|
||||||
|
|
||||||
// ----- TEST ON BLOCK FROM CONST MATRIX
|
// ----- TEST ON BLOCK FROM CONST MATRIX
|
||||||
std::make_tuple(c_block_main, i0, j0,
|
std::make_tuple(c_block_main, i0, j0, matrix_construct.ni,
|
||||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
matrix_construct.nj, int(NI), int(NJ)),
|
||||||
std::make_tuple(c_block_top_left_corner, 0, 0,
|
std::make_tuple(c_block_top_left_corner, 0, 0, matrix_construct.ni,
|
||||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
matrix_construct.nj, int(NI), int(NJ)),
|
||||||
std::make_tuple(c_block_top_right_corner, 0, matrix.cols() - matrix_construct.nj,
|
std::make_tuple(c_block_top_right_corner, 0,
|
||||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||||
std::make_tuple(c_block_bottom_left_corner, matrix.rows() - matrix_construct.ni, 0,
|
matrix_construct.nj, int(NI), int(NJ)),
|
||||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
std::make_tuple(c_block_bottom_left_corner,
|
||||||
std::make_tuple(c_block_bottom_right_corner, matrix.rows() - matrix_construct.ni,
|
matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni,
|
||||||
|
matrix_construct.nj, int(NI), int(NJ)),
|
||||||
|
std::make_tuple(c_block_bottom_right_corner,
|
||||||
|
matrix.rows() - matrix_construct.ni,
|
||||||
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||||
matrix_construct.nj, int(NI), int(NJ)),
|
matrix_construct.nj, int(NI), int(NJ)),
|
||||||
|
|
||||||
std::make_tuple(c_block_top_rows, 0, 0, matrix_construct.ni, matrix.cols(), int(NI), rotgen::Dynamic),
|
std::make_tuple(c_block_top_rows, 0, 0, matrix_construct.ni, matrix.cols(),
|
||||||
|
int(NI), rotgen::Dynamic),
|
||||||
std::make_tuple(c_block_middle_rows, i0, 0, matrix_construct.ni,
|
std::make_tuple(c_block_middle_rows, i0, 0, matrix_construct.ni,
|
||||||
matrix.cols(), int(NI), rotgen::Dynamic),
|
matrix.cols(), int(NI), rotgen::Dynamic),
|
||||||
std::make_tuple(c_block_bottom_rows, matrix.rows() - matrix_construct.ni,
|
std::make_tuple(c_block_bottom_rows, matrix.rows() - matrix_construct.ni, 0,
|
||||||
0, matrix_construct.ni, matrix.cols(), int(NI), rotgen::Dynamic),
|
matrix_construct.ni, matrix.cols(), int(NI),
|
||||||
|
rotgen::Dynamic),
|
||||||
|
|
||||||
std::make_tuple(c_block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
std::make_tuple(c_block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj,
|
||||||
std::make_tuple(c_block_middle_cols, 0, j0,
|
rotgen::Dynamic, int(NJ)),
|
||||||
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
std::make_tuple(c_block_middle_cols, 0, j0, matrix.rows(),
|
||||||
|
matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
||||||
std::make_tuple(c_block_right_cols, 0, matrix.cols() - matrix_construct.nj,
|
std::make_tuple(c_block_right_cols, 0, matrix.cols() - matrix_construct.nj,
|
||||||
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
matrix.rows(), matrix_construct.nj, rotgen::Dynamic,
|
||||||
|
int(NJ)),
|
||||||
|
|
||||||
std::make_tuple(c_block_row, i0, 0,
|
std::make_tuple(c_block_row, i0, 0, 1, matrix.cols(), 1, rotgen::Dynamic),
|
||||||
1, matrix.cols(), 1, rotgen::Dynamic),
|
std::make_tuple(c_block_col, 0, j0, matrix.rows(), 1, rotgen::Dynamic, 1),
|
||||||
std::make_tuple(c_block_col, 0, j0,
|
|
||||||
matrix.rows(), 1, rotgen::Dynamic, 1),
|
|
||||||
// -- Block to NON CONST
|
// -- Block to NON CONST
|
||||||
std::make_tuple(block_main, i0, j0,
|
std::make_tuple(block_main, i0, j0, matrix_construct.ni,
|
||||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
matrix_construct.nj, int(NI), int(NJ)),
|
||||||
std::make_tuple(block_top_left_corner, 0, 0,
|
std::make_tuple(block_top_left_corner, 0, 0, matrix_construct.ni,
|
||||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
matrix_construct.nj, int(NI), int(NJ)),
|
||||||
std::make_tuple(block_top_right_corner, 0, matrix.cols() - matrix_construct.nj,
|
std::make_tuple(block_top_right_corner, 0,
|
||||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||||
std::make_tuple(block_bottom_left_corner, matrix.rows() - matrix_construct.ni, 0,
|
matrix_construct.nj, int(NI), int(NJ)),
|
||||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
std::make_tuple(block_bottom_left_corner,
|
||||||
std::make_tuple(block_bottom_right_corner, matrix.rows() - matrix_construct.ni,
|
matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni,
|
||||||
|
matrix_construct.nj, int(NI), int(NJ)),
|
||||||
|
std::make_tuple(block_bottom_right_corner,
|
||||||
|
matrix.rows() - matrix_construct.ni,
|
||||||
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||||
matrix_construct.nj, int(NI), int(NJ)),
|
matrix_construct.nj, int(NI), int(NJ)),
|
||||||
|
|
||||||
std::make_tuple(block_top_rows, 0, 0, matrix_construct.ni, matrix.cols(), int(NI), rotgen::Dynamic),
|
std::make_tuple(block_top_rows, 0, 0, matrix_construct.ni, matrix.cols(),
|
||||||
|
int(NI), rotgen::Dynamic),
|
||||||
std::make_tuple(block_middle_rows, i0, 0, matrix_construct.ni,
|
std::make_tuple(block_middle_rows, i0, 0, matrix_construct.ni,
|
||||||
matrix.cols(), int(NI), rotgen::Dynamic),
|
matrix.cols(), int(NI), rotgen::Dynamic),
|
||||||
std::make_tuple(block_bottom_rows, matrix.rows() - matrix_construct.ni,
|
std::make_tuple(block_bottom_rows, matrix.rows() - matrix_construct.ni, 0,
|
||||||
0, matrix_construct.ni, matrix.cols(), int(NI), rotgen::Dynamic),
|
matrix_construct.ni, matrix.cols(), int(NI),
|
||||||
|
rotgen::Dynamic),
|
||||||
|
|
||||||
std::make_tuple(block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
std::make_tuple(block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj,
|
||||||
std::make_tuple(block_middle_cols, 0, j0,
|
rotgen::Dynamic, int(NJ)),
|
||||||
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
std::make_tuple(block_middle_cols, 0, j0, matrix.rows(),
|
||||||
|
matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
||||||
std::make_tuple(block_right_cols, 0, matrix.cols() - matrix_construct.nj,
|
std::make_tuple(block_right_cols, 0, matrix.cols() - matrix_construct.nj,
|
||||||
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
matrix.rows(), matrix_construct.nj, rotgen::Dynamic,
|
||||||
|
int(NJ)),
|
||||||
|
|
||||||
std::make_tuple(block_row, i0, 0,
|
std::make_tuple(block_row, i0, 0, 1, matrix.cols(), 1, rotgen::Dynamic),
|
||||||
1, matrix.cols(), 1, rotgen::Dynamic),
|
std::make_tuple(block_col, 0, j0, matrix.rows(), 1, rotgen::Dynamic, 1));
|
||||||
std::make_tuple(block_col, 0, j0,
|
|
||||||
matrix.rows(), 1, rotgen::Dynamic, 1)
|
|
||||||
);
|
|
||||||
|
|
||||||
std::apply([&](auto&&... block_entries)
|
std::apply(
|
||||||
{
|
[&](auto&&... block_entries) {
|
||||||
(([&]
|
(([&] {
|
||||||
{
|
auto&& [block, i_offset, j_offset, ni, nj, rows_ct, cols_ct] =
|
||||||
auto&& [block, i_offset, j_offset, ni, nj, rows_ct, cols_ct] = block_entries;
|
block_entries;
|
||||||
using block_t = std::remove_reference_t<decltype(block)>;
|
using block_t = std::remove_reference_t<decltype(block)>;
|
||||||
|
|
||||||
TTS_EQUAL(block_t::RowsAtCompileTime, rows_ct);
|
TTS_EQUAL(block_t::RowsAtCompileTime, rows_ct);
|
||||||
TTS_EQUAL(block_t::ColsAtCompileTime, cols_ct);
|
TTS_EQUAL(block_t::ColsAtCompileTime, cols_ct);
|
||||||
|
|
||||||
validate_block_behavior(matrix, block, i_offset, j_offset, ni, nj);
|
validate_block_behavior(matrix, block, i_offset, j_offset, ni, nj);
|
||||||
})(), ...);
|
})(),
|
||||||
}, blocks);
|
...);
|
||||||
|
},
|
||||||
|
blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
TTS_CASE_TPL("Check all dynamic block extractions on a dynamic row-major matrix", rotgen::tests::types)
|
TTS_CASE_TPL(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
"Check all dynamic block extractions on a dynamic row-major matrix",
|
||||||
|
rotgen::tests::types)<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value, 1>;
|
using mat_t =
|
||||||
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value, 1>;
|
||||||
|
|
||||||
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = {
|
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = {
|
||||||
{ {6, 11, [](rotgen::Index i, rotgen::Index j) { return T(i * 10 + j); }}, 1, 2, 3, 2 },
|
{{6, 11, [](rotgen::Index i, rotgen::Index j) { return T(i * 10 + j); }},
|
||||||
{ {7, 10, [](rotgen::Index i, rotgen::Index j) { return T(std::sin(i + j)); }}, 4, 4, 3, 3 },
|
1,
|
||||||
{ {5, 5, [](rotgen::Index i, rotgen::Index j) { return T((i + j) % 7); }}, 0, 0, 5, 5 },
|
2,
|
||||||
{ {9, 14, [](rotgen::Index i, rotgen::Index j) { return T(i+j + 3*j); }}, 3, 7, 1, 1 }
|
3,
|
||||||
};
|
2},
|
||||||
|
{{7, 10,
|
||||||
|
[](rotgen::Index i, rotgen::Index j) { return T(std::sin(i + j)); }},
|
||||||
|
4,
|
||||||
|
4,
|
||||||
|
3,
|
||||||
|
3},
|
||||||
|
{{5, 5, [](rotgen::Index i, rotgen::Index j) { return T((i + j) % 7); }},
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
5,
|
||||||
|
5},
|
||||||
|
{{9, 14, [](rotgen::Index i, rotgen::Index j) { return T(i + j + 3 * j); }},
|
||||||
|
3,
|
||||||
|
7,
|
||||||
|
1,
|
||||||
|
1}};
|
||||||
|
|
||||||
for (auto const& matrix_case : cases) {
|
for (auto const& matrix_case : cases)
|
||||||
|
{
|
||||||
test_dynamic_block_extraction<mat_t, T>(matrix_case);
|
test_dynamic_block_extraction<mat_t, T>(matrix_case);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check all dynamic block extractions on a static column-major matrix", rotgen::tests::types)
|
TTS_CASE_TPL(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
"Check all dynamic block extractions on a static column-major matrix",
|
||||||
|
rotgen::tests::types)<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, 4, 5, O::value, 0>;
|
using mat_t = rotgen::matrix<T, 4, 5, O::value, 0>;
|
||||||
|
|
||||||
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = {
|
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = {
|
||||||
{ {4, 5, [](auto i, auto j) { return T(2*i + j*j*j - 42); } }, 1, 2, 3, 2 },
|
{{4, 5, [](auto i, auto j) { return T(2 * i + j * j * j - 42); }},
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
2},
|
||||||
{{4, 5, [](auto i, auto j) { return T(std::tan(i * i * j)); }}, 0, 1, 2, 1},
|
{{4, 5, [](auto i, auto j) { return T(std::tan(i * i * j)); }}, 0, 1, 2, 1},
|
||||||
{ {4, 5, [](auto i, auto j) { return T((i*i + j*j) / 6); } }, 2, 0, 0, 0 }
|
{{4, 5, [](auto i, auto j) { return T((i * i + j * j) / 6); }},
|
||||||
};
|
2,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0}};
|
||||||
|
|
||||||
for (auto const& matrix_case : cases) {
|
for (auto const& matrix_case : cases)
|
||||||
|
{
|
||||||
test_dynamic_block_extraction<mat_t, T>(matrix_case);
|
test_dynamic_block_extraction<mat_t, T>(matrix_case);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check all static block extractions", rotgen::tests::types)
|
TTS_CASE_TPL("Check all static block extractions",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
|
|
||||||
test_static_block_extraction<mat_t, T, 1, 2>(
|
test_static_block_extraction<mat_t, T, 1, 2>(
|
||||||
rotgen::tests::static_matrix_block_test_case<mat_t, 1, 2>{
|
rotgen::tests::static_matrix_block_test_case<mat_t, 1, 2>{
|
||||||
{11, 11, [](rotgen::Index i, rotgen::Index j) { return T(i*i*i + 3*j - 127); } },
|
{11, 11,
|
||||||
3, 2
|
[](rotgen::Index i, rotgen::Index j) {
|
||||||
}
|
return T(i * i * i + 3 * j - 127);
|
||||||
);
|
}},
|
||||||
|
3,
|
||||||
|
2});
|
||||||
|
|
||||||
test_static_block_extraction<mat_t, double, 4, 3>(
|
test_static_block_extraction<mat_t, double, 4, 3>(
|
||||||
rotgen::tests::static_matrix_block_test_case<mat_t, 4, 3>{
|
rotgen::tests::static_matrix_block_test_case<mat_t, 4, 3>{
|
||||||
{14, 15,[](rotgen::Index i, rotgen::Index j) { return T(std::cos(i * j * 2)); }},
|
{14, 15,
|
||||||
5, 1
|
[](rotgen::Index i, rotgen::Index j) { return T(std::cos(i * j * 2)); }},
|
||||||
}
|
5,
|
||||||
);
|
1});
|
||||||
|
|
||||||
test_static_block_extraction<mat_t, double, 0, 0>(
|
test_static_block_extraction<mat_t, double, 0, 0>(
|
||||||
rotgen::tests::static_matrix_block_test_case<mat_t, 0, 0>{
|
rotgen::tests::static_matrix_block_test_case<mat_t, 0, 0>{
|
||||||
{5, 5, [](rotgen::Index i, rotgen::Index j) { return T((i + j) % 9); }},
|
{5, 5, [](rotgen::Index i, rotgen::Index j) { return T((i + j) % 9); }},
|
||||||
0, 0
|
0,
|
||||||
}
|
0});
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check vector-only extractions",
|
TTS_CASE_TPL("Check vector-only extractions",
|
||||||
rotgen::tests::types)<typename T, typename O>(
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
tts::type<tts::types<T, O>>) {
|
tts::type<tts::types<T, O>>)
|
||||||
|
{
|
||||||
auto run_case = [](auto&& matrix, auto&& block, int i_offset, int j_offset,
|
auto run_case = [](auto&& matrix, auto&& block, int i_offset, int j_offset,
|
||||||
int ni, int nj, auto const& rows_ct, auto const& cols_ct) {
|
int ni, int nj, auto const& rows_ct, auto const& cols_ct) {
|
||||||
using block_t = std::remove_reference_t<decltype(block)>;
|
using block_t = std::remove_reference_t<decltype(block)>;
|
||||||
|
|
@ -360,12 +445,12 @@ TTS_CASE_TPL("Check vector-only extractions",
|
||||||
validate_block_behavior(matrix, block, i_offset, j_offset, ni, nj);
|
validate_block_behavior(matrix, block, i_offset, j_offset, ni, nj);
|
||||||
};
|
};
|
||||||
|
|
||||||
if constexpr (O::value == rotgen::RowMajor) {
|
if constexpr (O::value == rotgen::RowMajor)
|
||||||
|
{
|
||||||
using mat_t = rotgen::matrix<T, 1, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, 1, rotgen::Dynamic, O::value>;
|
||||||
mat_t m(1, 11);
|
mat_t m(1, 11);
|
||||||
|
|
||||||
for (rotgen::Index i = 0; i < 11; ++i)
|
for (rotgen::Index i = 0; i < 11; ++i) m(i) = 1 + i;
|
||||||
m(i) = 1 + i;
|
|
||||||
|
|
||||||
run_case(m, head(m, 1), 0, 0, 1, 1, 1, rotgen::Dynamic);
|
run_case(m, head(m, 1), 0, 0, 1, 1, 1, rotgen::Dynamic);
|
||||||
run_case(m, head(m, 5), 0, 0, 1, 5, 1, rotgen::Dynamic);
|
run_case(m, head(m, 5), 0, 0, 1, 5, 1, rotgen::Dynamic);
|
||||||
|
|
@ -385,12 +470,13 @@ TTS_CASE_TPL("Check vector-only extractions",
|
||||||
run_case(m, segment<11>(m, 0), 0, 0, 1, 11, 1, 11);
|
run_case(m, segment<11>(m, 0), 0, 0, 1, 11, 1, 11);
|
||||||
run_case(m, segment<7>(m, 0), 0, 0, 1, 7, 1, 7);
|
run_case(m, segment<7>(m, 0), 0, 0, 1, 7, 1, 7);
|
||||||
run_case(m, segment<6>(m, 5), 0, 5, 1, 6, 1, 6);
|
run_case(m, segment<6>(m, 5), 0, 5, 1, 6, 1, 6);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, 1, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, 1, O::value>;
|
||||||
mat_t m(11, 1);
|
mat_t m(11, 1);
|
||||||
|
|
||||||
for (rotgen::Index i = 0; i < 11; ++i)
|
for (rotgen::Index i = 0; i < 11; ++i) m(i) = 1 + i;
|
||||||
m(i) = 1 + i;
|
|
||||||
|
|
||||||
run_case(m, head(m, 1), 0, 0, 1, 1, rotgen::Dynamic, 1);
|
run_case(m, head(m, 1), 0, 0, 1, 1, rotgen::Dynamic, 1);
|
||||||
run_case(m, head(m, 5), 0, 0, 5, 1, rotgen::Dynamic, 1);
|
run_case(m, head(m, 5), 0, 0, 5, 1, rotgen::Dynamic, 1);
|
||||||
|
|
|
||||||
|
|
@ -8,30 +8,34 @@
|
||||||
#include "unit/tests.hpp"
|
#include "unit/tests.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
void test_value ( const auto& matrix, auto value
|
void test_value(auto const& matrix,
|
||||||
, rotgen::Index i0, rotgen::Index j0
|
auto value,
|
||||||
, rotgen::Index rows, rotgen::Index cols
|
rotgen::Index i0,
|
||||||
)
|
rotgen::Index j0,
|
||||||
|
rotgen::Index rows,
|
||||||
|
rotgen::Index cols)
|
||||||
{
|
{
|
||||||
for (rotgen::Index r = 0; r < rows; ++r)
|
for (rotgen::Index r = 0; r < rows; ++r)
|
||||||
for (rotgen::Index c = 0; c < cols; ++c)
|
for (rotgen::Index c = 0; c < cols; ++c)
|
||||||
TTS_EQUAL(matrix(i0 + r, j0 + c), value);
|
TTS_EQUAL(matrix(i0 + r, j0 + c), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_identity( const auto& matrix
|
void test_identity(auto const& matrix,
|
||||||
, rotgen::Index i0, rotgen::Index j0
|
rotgen::Index i0,
|
||||||
, rotgen::Index rows, rotgen::Index cols
|
rotgen::Index j0,
|
||||||
)
|
rotgen::Index rows,
|
||||||
|
rotgen::Index cols)
|
||||||
{
|
{
|
||||||
for (rotgen::Index r = 0; r < rows; ++r)
|
for (rotgen::Index r = 0; r < rows; ++r)
|
||||||
for (rotgen::Index c = 0; c < cols; ++c)
|
for (rotgen::Index c = 0; c < cols; ++c)
|
||||||
TTS_EQUAL(matrix(i0 + r, j0 + c), r == c ? 1 : 0);
|
TTS_EQUAL(matrix(i0 + r, j0 + c), r == c ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_random( const auto& matrix
|
void test_random(auto const& matrix,
|
||||||
, rotgen::Index i0, rotgen::Index j0
|
rotgen::Index i0,
|
||||||
, rotgen::Index rows, rotgen::Index cols
|
rotgen::Index j0,
|
||||||
)
|
rotgen::Index rows,
|
||||||
|
rotgen::Index cols)
|
||||||
{
|
{
|
||||||
for (rotgen::Index r = 0; r < rows; ++r)
|
for (rotgen::Index r = 0; r < rows; ++r)
|
||||||
for (rotgen::Index c = 0; c < cols; ++c)
|
for (rotgen::Index c = 0; c < cols; ++c)
|
||||||
|
|
@ -41,11 +45,12 @@ void test_random( const auto& matrix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic block::setZero", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic block::setZero",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>>)
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
||||||
for (const auto& [matrix_desc, i0, j0, ni, nj] : cases)
|
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
|
||||||
{
|
{
|
||||||
auto [rows, cols, fn] = matrix_desc;
|
auto [rows, cols, fn] = matrix_desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
@ -61,13 +66,13 @@ TTS_CASE_TPL("Test dynamic block::setZero", rotgen::tests::types)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static block:setZero", rotgen::tests::types)
|
TTS_CASE_TPL("Test static block:setZero",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& d)
|
auto process = []<typename D>(D const& d) {
|
||||||
{
|
|
||||||
auto [desc, i0, j0] = d;
|
auto [desc, i0, j0] = d;
|
||||||
auto [rows, cols, fn] = desc;
|
auto [rows, cols, fn] = desc;
|
||||||
|
|
||||||
|
|
@ -86,11 +91,12 @@ TTS_CASE_TPL("Test static block:setZero", rotgen::tests::types)
|
||||||
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic block::setOnes", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic block::setOnes",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>>)
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
||||||
for (const auto& [matrix_desc, i0, j0, ni, nj] : cases)
|
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
|
||||||
{
|
{
|
||||||
auto [rows, cols, fn] = matrix_desc;
|
auto [rows, cols, fn] = matrix_desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
@ -106,13 +112,13 @@ TTS_CASE_TPL("Test dynamic block::setOnes", rotgen::tests::types)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static block:setOnes", rotgen::tests::types)
|
TTS_CASE_TPL("Test static block:setOnes",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& d)
|
auto process = []<typename D>(D const& d) {
|
||||||
{
|
|
||||||
auto [desc, i0, j0] = d;
|
auto [desc, i0, j0] = d;
|
||||||
auto [rows, cols, fn] = desc;
|
auto [rows, cols, fn] = desc;
|
||||||
|
|
||||||
|
|
@ -131,11 +137,12 @@ TTS_CASE_TPL("Test static block:setOnes", rotgen::tests::types)
|
||||||
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic block::setConstant", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic block::setConstant",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>>)
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
||||||
for (const auto& [matrix_desc, i0, j0, ni, nj] : cases)
|
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
|
||||||
{
|
{
|
||||||
auto [rows, cols, fn] = matrix_desc;
|
auto [rows, cols, fn] = matrix_desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
@ -151,13 +158,13 @@ TTS_CASE_TPL("Test dynamic block::setConstant", rotgen::tests::types)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static block:setConstant", rotgen::tests::types)
|
TTS_CASE_TPL("Test static block:setConstant",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& d)
|
auto process = []<typename D>(D const& d) {
|
||||||
{
|
|
||||||
auto [desc, i0, j0] = d;
|
auto [desc, i0, j0] = d;
|
||||||
auto [rows, cols, fn] = desc;
|
auto [rows, cols, fn] = desc;
|
||||||
|
|
||||||
|
|
@ -176,11 +183,12 @@ TTS_CASE_TPL("Test static block:setConstant", rotgen::tests::types)
|
||||||
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic block::setIdentity", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic block::setIdentity",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>>)
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
||||||
for (const auto& [matrix_desc, i0, j0, ni, nj] : cases)
|
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
|
||||||
{
|
{
|
||||||
auto [rows, cols, fn] = matrix_desc;
|
auto [rows, cols, fn] = matrix_desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
@ -196,13 +204,13 @@ TTS_CASE_TPL("Test dynamic block::setIdentity", rotgen::tests::types)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static block:setIdentity", rotgen::tests::types)
|
TTS_CASE_TPL("Test static block:setIdentity",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& d)
|
auto process = []<typename D>(D const& d) {
|
||||||
{
|
|
||||||
auto [desc, i0, j0] = d;
|
auto [desc, i0, j0] = d;
|
||||||
auto [rows, cols, fn] = desc;
|
auto [rows, cols, fn] = desc;
|
||||||
|
|
||||||
|
|
@ -221,11 +229,12 @@ TTS_CASE_TPL("Test static block:setIdentity", rotgen::tests::types)
|
||||||
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic block::setRandom", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic block::setRandom",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>>)
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
||||||
for (const auto& [matrix_desc, i0, j0, ni, nj] : cases)
|
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
|
||||||
{
|
{
|
||||||
auto [rows, cols, fn] = matrix_desc;
|
auto [rows, cols, fn] = matrix_desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
@ -241,14 +250,13 @@ TTS_CASE_TPL("Test dynamic block::setRandom", rotgen::tests::types)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TTS_CASE_TPL("Test static block:setRandom",
|
||||||
TTS_CASE_TPL("Test static block:setRandom", rotgen::tests::types)
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& d)
|
auto process = []<typename D>(D const& d) {
|
||||||
{
|
|
||||||
auto [desc, i0, j0] = d;
|
auto [desc, i0, j0] = d;
|
||||||
auto [rows, cols, fn] = desc;
|
auto [rows, cols, fn] = desc;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,12 @@
|
||||||
#include "unit/common/norms.hpp"
|
#include "unit/common/norms.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic block norm operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic block norm operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_block_references<T, O>();
|
||||||
for (const auto& [matrix_desc, i0, j0, ni, nj] : cases)
|
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
|
||||||
{
|
{
|
||||||
auto [rows, cols, fn] = matrix_desc;
|
auto [rows, cols, fn] = matrix_desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
@ -23,13 +24,13 @@ TTS_CASE_TPL("Test dynamic block norm operations", rotgen::tests::types)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static block norm operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test static block norm operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
auto const cases = rotgen::tests::generate_static_block_references<T, O>();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& d)
|
auto process = []<typename D>(D const& d) {
|
||||||
{
|
|
||||||
auto [desc, i0, j0] = d;
|
auto [desc, i0, j0] = d;
|
||||||
auto [rows, cols, fn] = desc;
|
auto [rows, cols, fn] = desc;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> m(rows, cols);
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,11 @@
|
||||||
#include <Eigen/Dense>
|
#include <Eigen/Dense>
|
||||||
|
|
||||||
template<typename MatrixType, typename T>
|
template<typename MatrixType, typename T>
|
||||||
void test_block_matrix_operations(rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct,
|
void test_block_matrix_operations(
|
||||||
auto b_init_fn, auto ops, auto self_ops)
|
rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct,
|
||||||
|
auto b_init_fn,
|
||||||
|
auto ops,
|
||||||
|
auto self_ops)
|
||||||
{
|
{
|
||||||
using EigenMatrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
using EigenMatrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
|
|
||||||
|
|
@ -64,8 +67,11 @@ void test_block_matrix_operations(rotgen::tests::matrix_block_test_case<MatrixTy
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType, typename T>
|
template<typename MatrixType, typename T>
|
||||||
void test_block_scalar_operations(rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct,
|
void test_block_scalar_operations(
|
||||||
auto scalar, auto ops, auto self_ops)
|
rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct,
|
||||||
|
auto scalar,
|
||||||
|
auto ops,
|
||||||
|
auto self_ops)
|
||||||
{
|
{
|
||||||
using EigenMatrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
using EigenMatrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
|
|
||||||
|
|
@ -99,12 +105,12 @@ void test_block_scalar_operations(rotgen::tests::matrix_block_test_case<MatrixTy
|
||||||
TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
|
TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < rows; ++r)
|
for (rotgen::Index r = 0; r < rows; ++r)
|
||||||
for (rotgen::Index c = 0; c < cols; ++c)
|
for (rotgen::Index c = 0; c < cols; ++c) TTS_EQUAL(a(r, c), ref_a(r, c));
|
||||||
TTS_EQUAL(a(r, c), ref_a(r, c));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType, typename T>
|
template<typename MatrixType, typename T>
|
||||||
void test_scalar_block_multiplications(rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct,
|
void test_scalar_block_multiplications(
|
||||||
|
rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct,
|
||||||
T scalar)
|
T scalar)
|
||||||
{
|
{
|
||||||
using EigenMatrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
using EigenMatrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
|
|
@ -122,10 +128,8 @@ void test_scalar_block_multiplications(rotgen::tests::matrix_block_test_case<Mat
|
||||||
for (rotgen::Index c = 0; c < cols; ++c)
|
for (rotgen::Index c = 0; c < cols; ++c)
|
||||||
ref_a(r, c) = a(r, c) = static_cast<T>(fn(r, c));
|
ref_a(r, c) = a(r, c) = static_cast<T>(fn(r, c));
|
||||||
|
|
||||||
auto a_block = rotgen::extract(a, i0, j0,
|
auto a_block = rotgen::extract(a, i0, j0, ni, nj);
|
||||||
ni, nj);
|
auto ref_a_block = ref_a.block(i0, j0, ni, nj);
|
||||||
auto ref_a_block = ref_a.block(i0, j0,
|
|
||||||
ni, nj);
|
|
||||||
|
|
||||||
auto a_scalar_multiplication = a_block * scalar;
|
auto a_scalar_multiplication = a_block * scalar;
|
||||||
auto scalar_a_multiplication = scalar * a_block;
|
auto scalar_a_multiplication = scalar * a_block;
|
||||||
|
|
@ -136,8 +140,10 @@ void test_scalar_block_multiplications(rotgen::tests::matrix_block_test_case<Mat
|
||||||
{
|
{
|
||||||
for (rotgen::Index c = 0; c < nj; ++c)
|
for (rotgen::Index c = 0; c < nj; ++c)
|
||||||
{
|
{
|
||||||
TTS_EQUAL(a_scalar_multiplication (r, c), a_scalar_multiplication_ref(r, c));
|
TTS_EQUAL(a_scalar_multiplication(r, c),
|
||||||
TTS_EQUAL(scalar_a_multiplication(r, c), scalar_a_multiplication_ref(r, c));
|
a_scalar_multiplication_ref(r, c));
|
||||||
|
TTS_EQUAL(scalar_a_multiplication(r, c),
|
||||||
|
scalar_a_multiplication_ref(r, c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,12 +155,12 @@ void test_scalar_block_multiplications(rotgen::tests::matrix_block_test_case<Mat
|
||||||
TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
|
TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < rows; ++r)
|
for (rotgen::Index r = 0; r < rows; ++r)
|
||||||
for (rotgen::Index c = 0; c < cols; ++c)
|
for (rotgen::Index c = 0; c < cols; ++c) TTS_EQUAL(a(r, c), ref_a(r, c));
|
||||||
TTS_EQUAL(a(r, c), ref_a(r, c));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType, typename T>
|
template<typename MatrixType, typename T>
|
||||||
void test_block_multiplication(rotgen::tests::matrix_block_test_case<MatrixType> const& a_matrix_construct,
|
void test_block_multiplication(
|
||||||
|
rotgen::tests::matrix_block_test_case<MatrixType> const& a_matrix_construct,
|
||||||
rotgen::tests::matrix_block_test_case<MatrixType> const& b_matrix_construct)
|
rotgen::tests::matrix_block_test_case<MatrixType> const& b_matrix_construct)
|
||||||
{
|
{
|
||||||
using EigenMatrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
using EigenMatrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
|
|
@ -165,7 +171,6 @@ void test_block_multiplication(rotgen::tests::matrix_block_test_case<MatrixType>
|
||||||
auto [b_d, b_i0, b_j0, b_ni, b_nj] = b_matrix_construct;
|
auto [b_d, b_i0, b_j0, b_ni, b_nj] = b_matrix_construct;
|
||||||
auto [b_rows, b_cols, b_fn] = b_d;
|
auto [b_rows, b_cols, b_fn] = b_d;
|
||||||
|
|
||||||
|
|
||||||
MatrixType a(a_rows, a_cols);
|
MatrixType a(a_rows, a_cols);
|
||||||
MatrixType b(b_rows, b_cols);
|
MatrixType b(b_rows, b_cols);
|
||||||
EigenMatrix ref_a(a_rows, a_cols);
|
EigenMatrix ref_a(a_rows, a_cols);
|
||||||
|
|
@ -179,7 +184,6 @@ void test_block_multiplication(rotgen::tests::matrix_block_test_case<MatrixType>
|
||||||
for (rotgen::Index c = 0; c < b_cols; ++c)
|
for (rotgen::Index c = 0; c < b_cols; ++c)
|
||||||
ref_b(r, c) = b(r, c) = static_cast<T>(b_fn(r, c));
|
ref_b(r, c) = b(r, c) = static_cast<T>(b_fn(r, c));
|
||||||
|
|
||||||
|
|
||||||
auto a_block = rotgen::extract(a, a_i0, a_j0, a_ni, a_nj);
|
auto a_block = rotgen::extract(a, a_i0, a_j0, a_ni, a_nj);
|
||||||
auto b_block = rotgen::extract(b, b_i0, b_j0, b_ni, b_nj);
|
auto b_block = rotgen::extract(b, b_i0, b_j0, b_ni, b_nj);
|
||||||
auto ref_a_block = ref_a.block(a_i0, a_j0, a_ni, a_nj);
|
auto ref_a_block = ref_a.block(a_i0, a_j0, a_ni, a_nj);
|
||||||
|
|
@ -202,106 +206,162 @@ void test_block_multiplication(rotgen::tests::matrix_block_test_case<MatrixType>
|
||||||
TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
|
TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < a_rows; ++r)
|
for (rotgen::Index r = 0; r < a_rows; ++r)
|
||||||
for (rotgen::Index c = 0; c < a_cols; ++c)
|
for (rotgen::Index c = 0; c < a_cols; ++c) TTS_EQUAL(a(r, c), ref_a(r, c));
|
||||||
TTS_EQUAL(a(r, c), ref_a(r, c));
|
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < b_rows; ++r)
|
for (rotgen::Index r = 0; r < b_rows; ++r)
|
||||||
for (rotgen::Index c = 0; c < b_cols; ++c)
|
for (rotgen::Index c = 0; c < b_cols; ++c) TTS_EQUAL(b(r, c), ref_b(r, c));
|
||||||
TTS_EQUAL(b(r, c), ref_b(r, c));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basic initializers
|
// Basic initializers
|
||||||
inline constexpr auto init_a = [](auto r, auto c) { return 9.9*r*r*r - 6*c -12; };
|
inline constexpr auto init_a = [](auto r, auto c) {
|
||||||
inline constexpr auto init_b = [](auto r, auto c) { return 3.1*r + 4.2*c - 12.3; };
|
return 9.9 * r * r * r - 6 * c - 12;
|
||||||
|
};
|
||||||
|
inline constexpr auto init_b = [](auto r, auto c) {
|
||||||
|
return 3.1 * r + 4.2 * c - 12.3;
|
||||||
|
};
|
||||||
inline constexpr auto init_0 = [](auto, auto) { return 0; };
|
inline constexpr auto init_0 = [](auto, auto) { return 0; };
|
||||||
|
|
||||||
TTS_CASE_TPL("Check block addition", rotgen::tests::types)
|
TTS_CASE_TPL("Check block addition",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto op = [](auto a, auto b) { return a + b; };
|
auto op = [](auto a, auto b) { return a + b; };
|
||||||
auto s_op = [](auto& a, auto b) { return a += b; };
|
auto s_op = [](auto& a, auto b) { return a += b; };
|
||||||
|
|
||||||
test_block_matrix_operations<mat_t, T>({{ 1, 1, init_a}, 0, 0, 1, 1}, init_b, op, s_op);
|
test_block_matrix_operations<mat_t, T>({{1, 1, init_a}, 0, 0, 1, 1}, init_b,
|
||||||
test_block_matrix_operations<mat_t, T>({{13, 15, init_a}, 1, 2, 3, 4}, init_b, op, s_op);
|
op, s_op);
|
||||||
test_block_matrix_operations<mat_t, T>({{ 5, 9, init_a}, 2, 2, 2, 2}, init_b, op, s_op);
|
test_block_matrix_operations<mat_t, T>({{13, 15, init_a}, 1, 2, 3, 4}, init_b,
|
||||||
test_block_matrix_operations<mat_t, T>({{15, 15, init_a}, 3, 4, 5, 5}, init_b, op, s_op);
|
op, s_op);
|
||||||
test_block_matrix_operations<mat_t, T>({{ 5, 5, init_b}, 1, 0, 3, 2}, init_a, op, s_op);
|
test_block_matrix_operations<mat_t, T>({{5, 9, init_a}, 2, 2, 2, 2}, init_b,
|
||||||
test_block_matrix_operations<mat_t, T>({{10, 1, init_a}, 0, 0, 5, 1}, init_b, op, s_op);
|
op, s_op);
|
||||||
test_block_matrix_operations<mat_t, T>({{ 1, 10, init_a}, 0, 0, 1, 5}, init_b, op, s_op);
|
test_block_matrix_operations<mat_t, T>({{15, 15, init_a}, 3, 4, 5, 5}, init_b,
|
||||||
test_block_matrix_operations<mat_t, T>({{21, 5, init_0}, 4, 4, 10, 1}, init_b, op, s_op);
|
op, s_op);
|
||||||
test_block_matrix_operations<mat_t, T>({{11, 7, init_a}, 2, 0, 7, 5}, init_0, op, s_op);
|
test_block_matrix_operations<mat_t, T>({{5, 5, init_b}, 1, 0, 3, 2}, init_a,
|
||||||
|
op, s_op);
|
||||||
|
test_block_matrix_operations<mat_t, T>({{10, 1, init_a}, 0, 0, 5, 1}, init_b,
|
||||||
|
op, s_op);
|
||||||
|
test_block_matrix_operations<mat_t, T>({{1, 10, init_a}, 0, 0, 1, 5}, init_b,
|
||||||
|
op, s_op);
|
||||||
|
test_block_matrix_operations<mat_t, T>({{21, 5, init_0}, 4, 4, 10, 1}, init_b,
|
||||||
|
op, s_op);
|
||||||
|
test_block_matrix_operations<mat_t, T>({{11, 7, init_a}, 2, 0, 7, 5}, init_0,
|
||||||
|
op, s_op);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check block subtraction", rotgen::tests::types)
|
TTS_CASE_TPL("Check block subtraction",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto op = [](auto a, auto b) { return a - b; };
|
auto op = [](auto a, auto b) { return a - b; };
|
||||||
auto s_op = [](auto& a, auto b) { return a -= b; };
|
auto s_op = [](auto& a, auto b) { return a -= b; };
|
||||||
|
|
||||||
test_block_matrix_operations<mat_t, T>({{ 1, 1, init_a}, 0, 0, 1, 1}, init_b, op, s_op);
|
test_block_matrix_operations<mat_t, T>({{1, 1, init_a}, 0, 0, 1, 1}, init_b,
|
||||||
test_block_matrix_operations<mat_t, T>({{ 1, 1, init_a}, 0, 0, 1, 1}, init_b, op, s_op);
|
op, s_op);
|
||||||
test_block_matrix_operations<mat_t, T>({{13, 15, init_a}, 1, 2, 3, 4}, init_b, op, s_op);
|
test_block_matrix_operations<mat_t, T>({{1, 1, init_a}, 0, 0, 1, 1}, init_b,
|
||||||
test_block_matrix_operations<mat_t, T>({{ 5, 9, init_a}, 2, 2, 2, 2}, init_b, op, s_op);
|
op, s_op);
|
||||||
test_block_matrix_operations<mat_t, T>({{15, 15, init_a}, 3, 4, 5, 5}, init_b, op, s_op);
|
test_block_matrix_operations<mat_t, T>({{13, 15, init_a}, 1, 2, 3, 4}, init_b,
|
||||||
test_block_matrix_operations<mat_t, T>({{ 5, 5, init_b}, 1, 0, 3, 2}, init_a, op, s_op);
|
op, s_op);
|
||||||
test_block_matrix_operations<mat_t, T>({{10, 1, init_a}, 0, 0, 5, 1}, init_b, op, s_op);
|
test_block_matrix_operations<mat_t, T>({{5, 9, init_a}, 2, 2, 2, 2}, init_b,
|
||||||
test_block_matrix_operations<mat_t, T>({{ 1, 10, init_a}, 0, 0, 1, 5}, init_b,op, s_op);
|
op, s_op);
|
||||||
test_block_matrix_operations<mat_t, T>({{21 , 5, init_0}, 4, 4, 10, 1}, init_b, op, s_op);
|
test_block_matrix_operations<mat_t, T>({{15, 15, init_a}, 3, 4, 5, 5}, init_b,
|
||||||
test_block_matrix_operations<mat_t, T>({{11 , 7, init_a}, 2, 0, 7, 5}, init_0, op, s_op);
|
op, s_op);
|
||||||
|
test_block_matrix_operations<mat_t, T>({{5, 5, init_b}, 1, 0, 3, 2}, init_a,
|
||||||
|
op, s_op);
|
||||||
|
test_block_matrix_operations<mat_t, T>({{10, 1, init_a}, 0, 0, 5, 1}, init_b,
|
||||||
|
op, s_op);
|
||||||
|
test_block_matrix_operations<mat_t, T>({{1, 10, init_a}, 0, 0, 1, 5}, init_b,
|
||||||
|
op, s_op);
|
||||||
|
test_block_matrix_operations<mat_t, T>({{21, 5, init_0}, 4, 4, 10, 1}, init_b,
|
||||||
|
op, s_op);
|
||||||
|
test_block_matrix_operations<mat_t, T>({{11, 7, init_a}, 2, 0, 7, 5}, init_0,
|
||||||
|
op, s_op);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check block multiplications", rotgen::tests::types)
|
TTS_CASE_TPL("Check block multiplications",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto init_id = [](rotgen::Index r, rotgen::Index c) { return r == c ? 1 : 0; };
|
auto init_id = [](rotgen::Index r, rotgen::Index c) {
|
||||||
|
return r == c ? 1 : 0;
|
||||||
test_block_multiplication<mat_t, T>({{ 1, 1, init_a }, 0, 0, 1, 1}, {{ 1, 1, init_b }, 0, 0, 1, 1});
|
|
||||||
test_block_multiplication<mat_t, T>({{13, 15, init_b }, 1, 2, 4, 4}, {{13, 15, init_b }, 0, 1, 4, 4});
|
|
||||||
test_block_multiplication<mat_t, T>({{ 6, 9, init_a }, 2, 2, 2, 2}, {{ 5, 9, init_b }, 2, 2, 2, 2});
|
|
||||||
test_block_multiplication<mat_t, T>({{15, 15, init_a }, 3, 4, 5, 5}, {{15, 15, init_b }, 0, 0, 5, 5});
|
|
||||||
test_block_multiplication<mat_t, T>({{ 5, 5, init_b }, 1, 0, 3, 3}, {{ 5, 5, init_a }, 0, 0, 3, 3});
|
|
||||||
test_block_multiplication<mat_t, T>({{11, 3, init_id}, 2, 0, 2, 2}, {{18, 7, init_a }, 2, 0, 2, 2});
|
|
||||||
test_block_multiplication<mat_t, T>({{10, 1, init_a }, 0, 0, 1, 1}, {{10, 1, init_a }, 0, 0, 1, 1});
|
|
||||||
test_block_multiplication<mat_t, T>({{ 1, 10, init_a }, 0, 0, 1, 1}, {{ 1, 10, init_id}, 0, 0, 1, 1});
|
|
||||||
test_block_multiplication<mat_t, T>({{21, 5, init_0 }, 1, 1, 3, 3}, {{12, 7, init_0 }, 4, 4, 3, 3});
|
|
||||||
test_block_multiplication<mat_t, T>({{11, 7, init_a }, 2, 0, 7, 7}, {{11, 11, init_a }, 2, 1, 7, 7});
|
|
||||||
test_block_multiplication<mat_t, T>({{11, 7, init_a }, 2, 0, 5, 5}, {{11, 12, init_id}, 0, 0, 5, 5});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check block multiplication with scalar", rotgen::tests::types)
|
test_block_multiplication<mat_t, T>({{1, 1, init_a}, 0, 0, 1, 1},
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
{{1, 1, init_b}, 0, 0, 1, 1});
|
||||||
|
test_block_multiplication<mat_t, T>({{13, 15, init_b}, 1, 2, 4, 4},
|
||||||
|
{{13, 15, init_b}, 0, 1, 4, 4});
|
||||||
|
test_block_multiplication<mat_t, T>({{6, 9, init_a}, 2, 2, 2, 2},
|
||||||
|
{{5, 9, init_b}, 2, 2, 2, 2});
|
||||||
|
test_block_multiplication<mat_t, T>({{15, 15, init_a}, 3, 4, 5, 5},
|
||||||
|
{{15, 15, init_b}, 0, 0, 5, 5});
|
||||||
|
test_block_multiplication<mat_t, T>({{5, 5, init_b}, 1, 0, 3, 3},
|
||||||
|
{{5, 5, init_a}, 0, 0, 3, 3});
|
||||||
|
test_block_multiplication<mat_t, T>({{11, 3, init_id}, 2, 0, 2, 2},
|
||||||
|
{{18, 7, init_a}, 2, 0, 2, 2});
|
||||||
|
test_block_multiplication<mat_t, T>({{10, 1, init_a}, 0, 0, 1, 1},
|
||||||
|
{{10, 1, init_a}, 0, 0, 1, 1});
|
||||||
|
test_block_multiplication<mat_t, T>({{1, 10, init_a}, 0, 0, 1, 1},
|
||||||
|
{{1, 10, init_id}, 0, 0, 1, 1});
|
||||||
|
test_block_multiplication<mat_t, T>({{21, 5, init_0}, 1, 1, 3, 3},
|
||||||
|
{{12, 7, init_0}, 4, 4, 3, 3});
|
||||||
|
test_block_multiplication<mat_t, T>({{11, 7, init_a}, 2, 0, 7, 7},
|
||||||
|
{{11, 11, init_a}, 2, 1, 7, 7});
|
||||||
|
test_block_multiplication<mat_t, T>({{11, 7, init_a}, 2, 0, 5, 5},
|
||||||
|
{{11, 12, init_id}, 0, 0, 5, 5});
|
||||||
|
};
|
||||||
|
|
||||||
|
TTS_CASE_TPL("Check block multiplication with scalar",
|
||||||
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
|
|
||||||
test_scalar_block_multiplications<mat_t, T>({{ 1, 1, init_a}, 0, 0, 1, 1}, T{ 3.5});
|
test_scalar_block_multiplications<mat_t, T>({{1, 1, init_a}, 0, 0, 1, 1},
|
||||||
test_scalar_block_multiplications<mat_t, T>({{13, 15, init_a}, 1, 2, 3, 4}, T{ 0.});
|
T{3.5});
|
||||||
test_scalar_block_multiplications<mat_t, T>({{ 5 , 9, init_a}, 2, 2, 2, 2}, T{-2.5});
|
test_scalar_block_multiplications<mat_t, T>({{13, 15, init_a}, 1, 2, 3, 4},
|
||||||
test_scalar_block_multiplications<mat_t, T>({{15, 15, init_a}, 3, 4, 5, 5}, T{ 42. });
|
T{0.});
|
||||||
test_scalar_block_multiplications<mat_t, T>({{ 5, 5, init_b}, 1, 0, 3, 2}, T{-5. });
|
test_scalar_block_multiplications<mat_t, T>({{5, 9, init_a}, 2, 2, 2, 2},
|
||||||
test_scalar_block_multiplications<mat_t, T>({{10, 1, init_a}, 0, 0, 5, 1}, T{ 1. });
|
T{-2.5});
|
||||||
test_scalar_block_multiplications<mat_t, T>({{ 1, 10, init_a}, 0, 0, 1, 5}, T{ 6. });
|
test_scalar_block_multiplications<mat_t, T>({{15, 15, init_a}, 3, 4, 5, 5},
|
||||||
test_scalar_block_multiplications<mat_t, T>({{21, 5, init_0}, 4, 4, 10, 1}, T{ 10.1});
|
T{42.});
|
||||||
test_scalar_block_multiplications<mat_t, T>({{11, 7, init_a}, 2, 0, 7, 5}, T{-0.5});
|
test_scalar_block_multiplications<mat_t, T>({{5, 5, init_b}, 1, 0, 3, 2},
|
||||||
|
T{-5.});
|
||||||
|
test_scalar_block_multiplications<mat_t, T>({{10, 1, init_a}, 0, 0, 5, 1},
|
||||||
|
T{1.});
|
||||||
|
test_scalar_block_multiplications<mat_t, T>({{1, 10, init_a}, 0, 0, 1, 5},
|
||||||
|
T{6.});
|
||||||
|
test_scalar_block_multiplications<mat_t, T>({{21, 5, init_0}, 4, 4, 10, 1},
|
||||||
|
T{10.1});
|
||||||
|
test_scalar_block_multiplications<mat_t, T>({{11, 7, init_a}, 2, 0, 7, 5},
|
||||||
|
T{-0.5});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check block division with scalar", rotgen::tests::types)
|
TTS_CASE_TPL("Check block division with scalar",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto op = [](auto a, auto b) { return a / b; };
|
auto op = [](auto a, auto b) { return a / b; };
|
||||||
auto s_op = [](auto& a, auto b) { return a /= b; };
|
auto s_op = [](auto& a, auto b) { return a /= b; };
|
||||||
|
|
||||||
test_block_scalar_operations<mat_t, T>({{ 1, 1, init_a}, 0, 0, 1, 1}, T{ 3.5}, op, s_op);
|
test_block_scalar_operations<mat_t, T>({{1, 1, init_a}, 0, 0, 1, 1}, T{3.5},
|
||||||
test_block_scalar_operations<mat_t, T>({{13, 15, init_a}, 1, 2, 3, 4}, T{-2.5}, op, s_op);
|
op, s_op);
|
||||||
test_block_scalar_operations<mat_t, T>({{ 5, 9, init_a}, 2, 2, 2, 2}, T{ 42. }, op, s_op);
|
test_block_scalar_operations<mat_t, T>({{13, 15, init_a}, 1, 2, 3, 4},
|
||||||
test_block_scalar_operations<mat_t, T>({{15, 15, init_a}, 3, 4, 5, 5}, T{-5. }, op, s_op);
|
T{-2.5}, op, s_op);
|
||||||
test_block_scalar_operations<mat_t, T>({{ 5, 5, init_b}, 1, 0, 3, 2}, T{ 1. }, op, s_op);
|
test_block_scalar_operations<mat_t, T>({{5, 9, init_a}, 2, 2, 2, 2}, T{42.},
|
||||||
test_block_scalar_operations<mat_t, T>({{10, 1, init_a}, 0, 0, 5, 1}, T{ 0. }, op, s_op);
|
op, s_op);
|
||||||
test_block_scalar_operations<mat_t, T>({{ 1, 10, init_a}, 0, 0, 1, 5}, T{ 6. }, op, s_op);
|
test_block_scalar_operations<mat_t, T>({{15, 15, init_a}, 3, 4, 5, 5}, T{-5.},
|
||||||
test_block_scalar_operations<mat_t, T>({{21, 5, init_0}, 4, 4, 10, 1}, T{ 10.}, op, s_op);
|
op, s_op);
|
||||||
test_block_scalar_operations<mat_t, T>({{11, 7, init_a}, 2, 0, 7, 5}, T{-0.5}, op, s_op);
|
test_block_scalar_operations<mat_t, T>({{5, 5, init_b}, 1, 0, 3, 2}, T{1.},
|
||||||
|
op, s_op);
|
||||||
|
test_block_scalar_operations<mat_t, T>({{10, 1, init_a}, 0, 0, 5, 1}, T{0.},
|
||||||
|
op, s_op);
|
||||||
|
test_block_scalar_operations<mat_t, T>({{1, 10, init_a}, 0, 0, 1, 5}, T{6.},
|
||||||
|
op, s_op);
|
||||||
|
test_block_scalar_operations<mat_t, T>({{21, 5, init_0}, 4, 4, 10, 1}, T{10.},
|
||||||
|
op, s_op);
|
||||||
|
test_block_scalar_operations<mat_t, T>({{11, 7, init_a}, 2, 0, 7, 5}, T{-0.5},
|
||||||
|
op, s_op);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
|
|
||||||
namespace rotgen::tests
|
namespace rotgen::tests
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T> void check_shape_functions(T original)
|
||||||
void check_shape_functions(T original)
|
|
||||||
{
|
{
|
||||||
using mat_t = matrix<typename T::value_type,Dynamic,Dynamic,T::storage_order>;
|
using mat_t =
|
||||||
|
matrix<typename T::value_type, Dynamic, Dynamic, T::storage_order>;
|
||||||
|
|
||||||
mat_t result(original.cols(), original.rows());
|
mat_t result(original.cols(), original.rows());
|
||||||
prepare([&](auto r, auto c) { return original(c, r); }, result);
|
prepare([&](auto r, auto c) { return original(c, r); }, result);
|
||||||
|
|
@ -57,10 +57,10 @@ namespace rotgen::tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T> void check_reduction_functions(T const& input)
|
||||||
void check_reduction_functions(const T& input)
|
|
||||||
{
|
{
|
||||||
using EigenMatrix = Eigen::Matrix<typename T::value_type, Eigen::Dynamic, Eigen::Dynamic>;
|
using EigenMatrix =
|
||||||
|
Eigen::Matrix<typename T::value_type, Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
|
|
||||||
EigenMatrix ref(input.rows(), input.cols());
|
EigenMatrix ref(input.rows(), input.cols());
|
||||||
prepare([&](auto r, auto c) { return input(r, c); }, ref);
|
prepare([&](auto r, auto c) { return input(r, c); }, ref);
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,12 @@
|
||||||
|
|
||||||
namespace rotgen::tests
|
namespace rotgen::tests
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T> void check_cwise_functions(T const& input)
|
||||||
void check_cwise_functions(const T& input)
|
|
||||||
{
|
{
|
||||||
using EigenMatrix = Eigen::Matrix<typename T::value_type, Eigen::Dynamic, Eigen::Dynamic>;
|
using EigenMatrix =
|
||||||
using mat_t = matrix<typename T::value_type,Dynamic,Dynamic,T::storage_order>;
|
Eigen::Matrix<typename T::value_type, Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
|
using mat_t =
|
||||||
|
matrix<typename T::value_type, Dynamic, Dynamic, T::storage_order>;
|
||||||
|
|
||||||
TTS_WHEN("Unary Cwise operations")
|
TTS_WHEN("Unary Cwise operations")
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
|
|
||||||
namespace rotgen::tests
|
namespace rotgen::tests
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T> void check_norms_functions(T const& input)
|
||||||
void check_norms_functions(const T& input)
|
|
||||||
{
|
{
|
||||||
using EigenMatrix = Eigen::Matrix<typename T::value_type, Eigen::Dynamic, Eigen::Dynamic>;
|
using EigenMatrix =
|
||||||
|
Eigen::Matrix<typename T::value_type, Eigen::Dynamic, Eigen::Dynamic>;
|
||||||
|
|
||||||
EigenMatrix ref(input.rows(), input.cols());
|
EigenMatrix ref(input.rows(), input.cols());
|
||||||
|
|
||||||
|
|
@ -25,12 +25,14 @@ namespace rotgen::tests
|
||||||
TTS_EQUAL(rotgen::squaredNorm(input), ref.squaredNorm());
|
TTS_EQUAL(rotgen::squaredNorm(input), ref.squaredNorm());
|
||||||
TTS_EQUAL(rotgen::lpNorm<1>(input), ref.template lpNorm<1>());
|
TTS_EQUAL(rotgen::lpNorm<1>(input), ref.template lpNorm<1>());
|
||||||
TTS_EQUAL(rotgen::lpNorm<2>(input), ref.template lpNorm<2>());
|
TTS_EQUAL(rotgen::lpNorm<2>(input), ref.template lpNorm<2>());
|
||||||
TTS_EQUAL(rotgen::lpNorm<rotgen::Infinity>(input) , ref.template lpNorm<Eigen::Infinity>());
|
TTS_EQUAL(rotgen::lpNorm<rotgen::Infinity>(input),
|
||||||
|
ref.template lpNorm<Eigen::Infinity>());
|
||||||
|
|
||||||
if constexpr (T::IsVectorAtCompileTime)
|
if constexpr (T::IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
EigenMatrix e_norm = ref.normalized();
|
EigenMatrix e_norm = ref.normalized();
|
||||||
using mat_t = rotgen::matrix<typename T::value_type,rotgen::Dynamic,rotgen::Dynamic,T::storage_order>;
|
using mat_t = rotgen::matrix<typename T::value_type, rotgen::Dynamic,
|
||||||
|
rotgen::Dynamic, T::storage_order>;
|
||||||
mat_t norm_ref(input.rows(), input.cols());
|
mat_t norm_ref(input.rows(), input.cols());
|
||||||
prepare([&](auto r, auto c) { return e_norm(r, c); }, norm_ref);
|
prepare([&](auto r, auto c) { return e_norm(r, c); }, norm_ref);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,7 @@ namespace rotgen::tests
|
||||||
std::function<double(std::size_t, std::size_t)> init_fn;
|
std::function<double(std::size_t, std::size_t)> init_fn;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename MatrixType>
|
template<typename MatrixType> struct matrix_block_test_case
|
||||||
struct matrix_block_test_case
|
|
||||||
{
|
{
|
||||||
matrix_descriptor matrix_desc;
|
matrix_descriptor matrix_desc;
|
||||||
rotgen::Index i0, j0, ni, nj;
|
rotgen::Index i0, j0, ni, nj;
|
||||||
|
|
@ -43,25 +42,25 @@ namespace rotgen::tests
|
||||||
rotgen::Index i0, j0;
|
rotgen::Index i0, j0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void prepare(rotgen::Index rows, rotgen::Index cols, auto const &init_fn, auto& output)
|
void prepare(rotgen::Index rows,
|
||||||
|
rotgen::Index cols,
|
||||||
|
auto const& init_fn,
|
||||||
|
auto& output)
|
||||||
{
|
{
|
||||||
for (rotgen::Index r = 0; r < rows; ++r)
|
for (rotgen::Index r = 0; r < rows; ++r)
|
||||||
for (rotgen::Index c = 0; c < cols; ++c)
|
for (rotgen::Index c = 0; c < cols; ++c) output(r, c) = init_fn(r, c);
|
||||||
output(r,c) = init_fn(r, c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare(auto fn, auto& output)
|
void prepare(auto fn, auto& output)
|
||||||
{
|
{
|
||||||
for (rotgen::Index r = 0; r < output.rows(); ++r)
|
for (rotgen::Index r = 0; r < output.rows(); ++r)
|
||||||
for (rotgen::Index c = 0; c < output.cols(); ++c)
|
for (rotgen::Index c = 0; c < output.cols(); ++c) output(r, c) = fn(r, c);
|
||||||
output(r,c) = fn(r, c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto generate_matrix_references()
|
auto generate_matrix_references()
|
||||||
{
|
{
|
||||||
auto fn = [](auto r, auto c) { return r + 3 * c - 2.5; };
|
auto fn = [](auto r, auto c) { return r + 3 * c - 2.5; };
|
||||||
std::vector<rotgen::tests::matrix_descriptor> cases =
|
std::vector<rotgen::tests::matrix_descriptor> cases = {
|
||||||
{
|
|
||||||
// Singular matrix
|
// Singular matrix
|
||||||
{1, 1, fn},
|
{1, 1, fn},
|
||||||
// Square matrix below MAX_SIZE
|
// Square matrix below MAX_SIZE
|
||||||
|
|
@ -81,8 +80,7 @@ namespace rotgen::tests
|
||||||
// Thick matrix at MAX_SIZE
|
// Thick matrix at MAX_SIZE
|
||||||
{2, 8, fn},
|
{2, 8, fn},
|
||||||
// Thick matrix above MAX_SIZE
|
// Thick matrix above MAX_SIZE
|
||||||
{3, 10, fn}
|
{3, 10, fn}};
|
||||||
};
|
|
||||||
|
|
||||||
return cases;
|
return cases;
|
||||||
}
|
}
|
||||||
|
|
@ -90,9 +88,7 @@ namespace rotgen::tests
|
||||||
auto generate_static_matrix_references()
|
auto generate_static_matrix_references()
|
||||||
{
|
{
|
||||||
auto fn = [](auto r, auto c) { return r + 3 * c - 2.5; };
|
auto fn = [](auto r, auto c) { return r + 3 * c - 2.5; };
|
||||||
std::tuple cases =
|
std::tuple cases = {// Singular matrix
|
||||||
{
|
|
||||||
// Singular matrix
|
|
||||||
static_matrix_descriptor<1, 1>{fn},
|
static_matrix_descriptor<1, 1>{fn},
|
||||||
// Square matrix below MAX_SIZE
|
// Square matrix below MAX_SIZE
|
||||||
static_matrix_descriptor<3, 3>{fn},
|
static_matrix_descriptor<3, 3>{fn},
|
||||||
|
|
@ -111,21 +107,19 @@ namespace rotgen::tests
|
||||||
// Thick matrix at MAX_SIZE
|
// Thick matrix at MAX_SIZE
|
||||||
static_matrix_descriptor<2, 8>{fn},
|
static_matrix_descriptor<2, 8>{fn},
|
||||||
// Thick matrix above MAX_SIZE
|
// Thick matrix above MAX_SIZE
|
||||||
static_matrix_descriptor< 3,10>{fn}
|
static_matrix_descriptor<3, 10>{fn}};
|
||||||
};
|
|
||||||
|
|
||||||
return cases;
|
return cases;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename O>
|
template<typename T, typename O> auto generate_block_references()
|
||||||
auto generate_block_references()
|
|
||||||
{
|
{
|
||||||
rotgen::tests::matrix_descriptor base{16,16,[](auto r, auto c) { return r + 3 * c - 2.5; }};
|
rotgen::tests::matrix_descriptor base{
|
||||||
|
16, 16, [](auto r, auto c) { return r + 3 * c - 2.5; }};
|
||||||
|
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
|
|
||||||
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases =
|
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = {
|
||||||
{
|
|
||||||
// Singular blocks
|
// Singular blocks
|
||||||
{base, 0, 0, 1, 1},
|
{base, 0, 0, 1, 1},
|
||||||
{base, 3, 2, 1, 1},
|
{base, 3, 2, 1, 1},
|
||||||
|
|
@ -148,20 +142,19 @@ namespace rotgen::tests
|
||||||
// Thick block at MAX_SIZE
|
// Thick block at MAX_SIZE
|
||||||
{base, 6, 3, 2, 8},
|
{base, 6, 3, 2, 8},
|
||||||
// Thick block above MAX_SIZE
|
// Thick block above MAX_SIZE
|
||||||
{base,6,3, 3, 7}
|
{base, 6, 3, 3, 7}};
|
||||||
};
|
|
||||||
|
|
||||||
return cases;
|
return cases;
|
||||||
}
|
}
|
||||||
template<typename T, typename O>
|
|
||||||
auto generate_static_block_references()
|
template<typename T, typename O> auto generate_static_block_references()
|
||||||
{
|
{
|
||||||
rotgen::tests::matrix_descriptor base{16,16,[](auto r, auto c) { return r + 3 * c - 2.5; }};
|
rotgen::tests::matrix_descriptor base{
|
||||||
|
16, 16, [](auto r, auto c) { return r + 3 * c - 2.5; }};
|
||||||
|
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
|
|
||||||
std::tuple cases =
|
std::tuple cases = {
|
||||||
{
|
|
||||||
// Singular blocks
|
// Singular blocks
|
||||||
static_matrix_block_test_case<mat_t, 1, 1>{base, 0, 0},
|
static_matrix_block_test_case<mat_t, 1, 1>{base, 0, 0},
|
||||||
static_matrix_block_test_case<mat_t, 1, 1>{base, 3, 2},
|
static_matrix_block_test_case<mat_t, 1, 1>{base, 3, 2},
|
||||||
|
|
@ -184,8 +177,7 @@ namespace rotgen::tests
|
||||||
// Thick block at MAX_SIZE
|
// Thick block at MAX_SIZE
|
||||||
static_matrix_block_test_case<mat_t, 2, 8>{base, 6, 3},
|
static_matrix_block_test_case<mat_t, 2, 8>{base, 6, 3},
|
||||||
// Thick block above MAX_SIZE
|
// Thick block above MAX_SIZE
|
||||||
static_matrix_block_test_case<mat_t, 3, 7>{base,6,3}
|
static_matrix_block_test_case<mat_t, 3, 7>{base, 6, 3}};
|
||||||
};
|
|
||||||
|
|
||||||
return cases;
|
return cases;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,17 @@
|
||||||
#include "unit/tests.hpp"
|
#include "unit/tests.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("System solver using QR", rotgen::tests::types)
|
TTS_CASE_TPL("System solver using QR",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic>
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic> a{{2.3, -1, 0.1},
|
||||||
a { { 2.3, -1, 0.1}
|
{-1.6, 2.6, -1},
|
||||||
, {-1.6, 2.6, -1}
|
{0.3, -1, 2}};
|
||||||
, { 0.3, -1, 2}
|
|
||||||
};
|
|
||||||
|
|
||||||
rotgen::matrix<T, rotgen::Dynamic, 1> b(3, 1);
|
rotgen::matrix<T, rotgen::Dynamic, 1> b(3, 1);
|
||||||
b(0) = b(2) = 1; b(1) = 0;
|
b(0) = b(2) = 1;
|
||||||
|
b(1) = 0;
|
||||||
|
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic> r(3, 1), error;
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic> r(3, 1), error;
|
||||||
|
|
||||||
|
|
@ -28,7 +28,8 @@ TTS_CASE_TPL("System solver using QR", rotgen::tests::types)
|
||||||
error = a * r - b;
|
error = a * r - b;
|
||||||
auto eps = std::numeric_limits<T>::epsilon();
|
auto eps = std::numeric_limits<T>::epsilon();
|
||||||
|
|
||||||
TTS_LESS(rotgen::maxCoeff(rotgen::abs(error)) / eps, 5)
|
TTS_LESS(rotgen::maxCoeff(rotgen::abs(error)) / eps, 5) << "Result:\n"
|
||||||
<< "Result:\n" << r << "\n"
|
<< r << "\n"
|
||||||
<< "Residuals:\n" << error << "\n";
|
<< "Residuals:\n"
|
||||||
|
<< error << "\n";
|
||||||
};
|
};
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
#include "unit/tests.hpp"
|
#include "unit/tests.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("rowwise API", rotgen::tests::types)
|
TTS_CASE_TPL("rowwise API", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using e_t = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, O::value>;
|
using e_t = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, O::value>;
|
||||||
e_t ref = e_t::Random(4, 4);
|
e_t ref = e_t::Random(4, 4);
|
||||||
|
|
@ -20,17 +20,24 @@ TTS_CASE_TPL("rowwise API", rotgen::tests::types)
|
||||||
|
|
||||||
auto rw = rotgen::rowwise(mat);
|
auto rw = rotgen::rowwise(mat);
|
||||||
|
|
||||||
for(rotgen::Index i=0;i<mat.rows();++i) TTS_EQUAL(rw.sum()(i) , ref_rw.sum()(i) );
|
for (rotgen::Index i = 0; i < mat.rows(); ++i)
|
||||||
for(rotgen::Index i=0;i<mat.rows();++i) TTS_EQUAL(rw.mean()(i) , ref_rw.mean()(i) );
|
TTS_EQUAL(rw.sum()(i), ref_rw.sum()(i));
|
||||||
for(rotgen::Index i=0;i<mat.rows();++i) TTS_EQUAL(rw.prod()(i) , ref_rw.prod()(i) );
|
for (rotgen::Index i = 0; i < mat.rows(); ++i)
|
||||||
for(rotgen::Index i=0;i<mat.rows();++i) TTS_EQUAL(rw.maxCoeff()(i) , ref_rw.maxCoeff()(i) );
|
TTS_EQUAL(rw.mean()(i), ref_rw.mean()(i));
|
||||||
for(rotgen::Index i=0;i<mat.rows();++i) TTS_EQUAL(rw.minCoeff()(i) , ref_rw.minCoeff()(i) );
|
for (rotgen::Index i = 0; i < mat.rows(); ++i)
|
||||||
for(rotgen::Index i=0;i<mat.rows();++i) TTS_EQUAL(rw.squaredNorm()(i) , ref_rw.squaredNorm()(i) );
|
TTS_EQUAL(rw.prod()(i), ref_rw.prod()(i));
|
||||||
for(rotgen::Index i=0;i<mat.rows();++i) TTS_EQUAL(rw.norm()(i) , ref_rw.norm()(i) );
|
for (rotgen::Index i = 0; i < mat.rows(); ++i)
|
||||||
|
TTS_EQUAL(rw.maxCoeff()(i), ref_rw.maxCoeff()(i));
|
||||||
|
for (rotgen::Index i = 0; i < mat.rows(); ++i)
|
||||||
|
TTS_EQUAL(rw.minCoeff()(i), ref_rw.minCoeff()(i));
|
||||||
|
for (rotgen::Index i = 0; i < mat.rows(); ++i)
|
||||||
|
TTS_EQUAL(rw.squaredNorm()(i), ref_rw.squaredNorm()(i));
|
||||||
|
for (rotgen::Index i = 0; i < mat.rows(); ++i)
|
||||||
|
TTS_EQUAL(rw.norm()(i), ref_rw.norm()(i));
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("colwise API", rotgen::tests::types)
|
TTS_CASE_TPL("colwise API", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using e_t = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, O::value>;
|
using e_t = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, O::value>;
|
||||||
e_t ref = e_t::Random(4, 4);
|
e_t ref = e_t::Random(4, 4);
|
||||||
|
|
@ -41,14 +48,18 @@ TTS_CASE_TPL("colwise API", rotgen::tests::types)
|
||||||
|
|
||||||
auto rw = rotgen::colwise(mat);
|
auto rw = rotgen::colwise(mat);
|
||||||
|
|
||||||
for(rotgen::Index i=0;i<mat.cols();++i) TTS_EQUAL(rw.sum()(i) , ref_rw.sum()(i) );
|
for (rotgen::Index i = 0; i < mat.cols(); ++i)
|
||||||
for(rotgen::Index i=0;i<mat.cols();++i) TTS_EQUAL(rw.mean()(i) , ref_rw.mean()(i) );
|
TTS_EQUAL(rw.sum()(i), ref_rw.sum()(i));
|
||||||
for(rotgen::Index i=0;i<mat.cols();++i) TTS_EQUAL(rw.prod()(i) , ref_rw.prod()(i) );
|
for (rotgen::Index i = 0; i < mat.cols(); ++i)
|
||||||
for(rotgen::Index i=0;i<mat.cols();++i) TTS_EQUAL(rw.maxCoeff()(i) , ref_rw.maxCoeff()(i) );
|
TTS_EQUAL(rw.mean()(i), ref_rw.mean()(i));
|
||||||
for(rotgen::Index i=0;i<mat.cols();++i) TTS_EQUAL(rw.minCoeff()(i) , ref_rw.minCoeff()(i) );
|
for (rotgen::Index i = 0; i < mat.cols(); ++i)
|
||||||
for(rotgen::Index i=0;i<mat.cols();++i) TTS_EQUAL(rw.squaredNorm()(i) , ref_rw.squaredNorm()(i) );
|
TTS_EQUAL(rw.prod()(i), ref_rw.prod()(i));
|
||||||
for(rotgen::Index i=0;i<mat.cols();++i) TTS_EQUAL(rw.norm()(i) , ref_rw.norm()(i) );
|
for (rotgen::Index i = 0; i < mat.cols(); ++i)
|
||||||
|
TTS_EQUAL(rw.maxCoeff()(i), ref_rw.maxCoeff()(i));
|
||||||
|
for (rotgen::Index i = 0; i < mat.cols(); ++i)
|
||||||
|
TTS_EQUAL(rw.minCoeff()(i), ref_rw.minCoeff()(i));
|
||||||
|
for (rotgen::Index i = 0; i < mat.cols(); ++i)
|
||||||
|
TTS_EQUAL(rw.squaredNorm()(i), ref_rw.squaredNorm()(i));
|
||||||
|
for (rotgen::Index i = 0; i < mat.cols(); ++i)
|
||||||
|
TTS_EQUAL(rw.norm()(i), ref_rw.norm()(i));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,27 +10,28 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
template <typename MatrixType>
|
template<typename MatrixType> struct MatrixDescriptor
|
||||||
struct MatrixDescriptor
|
|
||||||
{
|
{
|
||||||
std::size_t rows, cols;
|
std::size_t rows, cols;
|
||||||
std::function<void(MatrixType&, std::size_t, std::size_t)> init_fn;
|
std::function<void(MatrixType&, std::size_t, std::size_t)> init_fn;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename MatrixType, std::size_t N>
|
template<typename MatrixType, std::size_t N>
|
||||||
void test_matrix_sizes(std::size_t rows, std::size_t cols,
|
void test_matrix_sizes(
|
||||||
const std::function<void(MatrixType &, std::size_t, std::size_t)> &init_fn,
|
std::size_t rows,
|
||||||
const std::array<std::pair<int, int>, N>& resize_dimensions)
|
std::size_t cols,
|
||||||
|
std::function<void(MatrixType&, std::size_t, std::size_t)> const& init_fn,
|
||||||
|
std::array<std::pair<int, int>, N> const& resize_dimensions)
|
||||||
{
|
{
|
||||||
MatrixType matrix(rows, cols);
|
MatrixType matrix(rows, cols);
|
||||||
|
|
||||||
for (std::size_t r = 0; r < rows; ++r)
|
for (std::size_t r = 0; r < rows; ++r)
|
||||||
for (std::size_t c = 0; c < cols; ++c)
|
for (std::size_t c = 0; c < cols; ++c) init_fn(matrix, r, c);
|
||||||
init_fn(matrix, r, c);
|
|
||||||
|
|
||||||
TTS_EQUAL(rotgen::size(matrix), rows * cols);
|
TTS_EQUAL(rotgen::size(matrix), rows * cols);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < N; ++i) {
|
for (std::size_t i = 0; i < N; ++i)
|
||||||
|
{
|
||||||
int r = resize_dimensions[i].first;
|
int r = resize_dimensions[i].first;
|
||||||
int c = resize_dimensions[i].second;
|
int c = resize_dimensions[i].second;
|
||||||
|
|
||||||
|
|
@ -46,16 +47,14 @@ void test_matrix_sizes(std::size_t rows, std::size_t cols,
|
||||||
|
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for (std::size_t r = 0; r < rows; ++r)
|
for (std::size_t r = 0; r < rows; ++r)
|
||||||
for(std::size_t c=0;c<cols;++c)
|
for (std::size_t c = 0; c < cols; ++c) matrix(r, c) = i++;
|
||||||
matrix(r, c) = i++;
|
|
||||||
|
|
||||||
rotgen::conservativeResize(matrix, rows + 3, cols + 2);
|
rotgen::conservativeResize(matrix, rows + 3, cols + 2);
|
||||||
TTS_EQUAL(rotgen::size(matrix), (rows + 3) * (cols + 2));
|
TTS_EQUAL(rotgen::size(matrix), (rows + 3) * (cols + 2));
|
||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
for (std::size_t r = 0; r < rows; ++r)
|
for (std::size_t r = 0; r < rows; ++r)
|
||||||
for(std::size_t c=0;c<cols;++c)
|
for (std::size_t c = 0; c < cols; ++c) TTS_EQUAL(matrix(r, c), i++);
|
||||||
TTS_EQUAL(matrix(r,c),i++);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TTS_CASE("Matrix size-related operations")
|
TTS_CASE("Matrix size-related operations")
|
||||||
|
|
@ -63,18 +62,37 @@ TTS_CASE("Matrix size-related operations")
|
||||||
std::vector<MatrixDescriptor<rotgen::matrix<double>>> test_matrices = {
|
std::vector<MatrixDescriptor<rotgen::matrix<double>>> test_matrices = {
|
||||||
{3, 3, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = r + c; }},
|
{3, 3, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = r + c; }},
|
||||||
{2, 3, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = 0.0; }},
|
{2, 3, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = 0.0; }},
|
||||||
{2, 7, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = -r*r*r - c*c - 1.23; }},
|
{2, 7,
|
||||||
{17, 3, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = r*c + 0.98; }},
|
[](auto& m, std::size_t r, std::size_t c) {
|
||||||
|
m(r, c) = -r * r * r - c * c - 1.23;
|
||||||
|
}},
|
||||||
|
{17, 3,
|
||||||
|
[](auto& m, std::size_t r, std::size_t c) { m(r, c) = r * c + 0.98; }},
|
||||||
{1, 1, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = 42.0; }},
|
{1, 1, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = 42.0; }},
|
||||||
{10, 11, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = std::tan(r + c); }},
|
{10, 11,
|
||||||
{1, 5, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = -1.5*r + 2.56*c + 3.33; }},
|
[](auto& m, std::size_t r, std::size_t c) { m(r, c) = std::tan(r + c); }},
|
||||||
{7, 1, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = (r == c ? 1.0 : 0.0); }},
|
{1, 5,
|
||||||
{0, 0, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = (r == c ? 1.0 : 0.0); }},
|
[](auto& m, std::size_t r, std::size_t c) {
|
||||||
|
m(r, c) = -1.5 * r + 2.56 * c + 3.33;
|
||||||
|
}},
|
||||||
|
{7, 1,
|
||||||
|
[](auto& m, std::size_t r, std::size_t c) {
|
||||||
|
m(r, c) = (r == c ? 1.0 : 0.0);
|
||||||
|
}},
|
||||||
|
{0, 0,
|
||||||
|
[](auto& m, std::size_t r, std::size_t c) {
|
||||||
|
m(r, c) = (r == c ? 1.0 : 0.0);
|
||||||
|
}},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto& [rows, cols, init_fn] : test_matrices)
|
for (auto const& [rows, cols, init_fn] : test_matrices)
|
||||||
test_matrix_sizes<rotgen::matrix<double>>(rows, cols, init_fn, std::array{
|
test_matrix_sizes<rotgen::matrix<double>>(rows, cols, init_fn,
|
||||||
std::pair{1, 2}, std::pair{11, 17}, std::pair{4, 5},
|
std::array{
|
||||||
std::pair{9, 1}, std::pair{3, 8}, std::pair{22, 0},
|
std::pair{1, 2},
|
||||||
|
std::pair{11, 17},
|
||||||
|
std::pair{4, 5},
|
||||||
|
std::pair{9, 1},
|
||||||
|
std::pair{3, 8},
|
||||||
|
std::pair{22, 0},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,18 @@
|
||||||
#include "unit/tests.hpp"
|
#include "unit/tests.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("SVD decomposition - Dynamic case", rotgen::tests::types)
|
TTS_CASE_TPL("SVD decomposition - Dynamic case",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
int rank, i = 5;
|
int rank, i = 5;
|
||||||
auto eps = std::numeric_limits<T>::epsilon();
|
auto eps = std::numeric_limits<T>::epsilon();
|
||||||
|
|
||||||
auto m = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>::Random(5,5);
|
auto m =
|
||||||
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>::Random(5, 5);
|
||||||
auto decomp = rotgen::svd(m);
|
auto decomp = rotgen::svd(m);
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
rank = decomp.rank();
|
rank = decomp.rank();
|
||||||
|
|
||||||
auto u = decomp.U(rank);
|
auto u = decomp.U(rank);
|
||||||
|
|
@ -32,8 +33,10 @@ TTS_CASE_TPL("SVD decomposition - Dynamic case", rotgen::tests::types)
|
||||||
auto error = m - rec;
|
auto error = m - rec;
|
||||||
|
|
||||||
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 16.)
|
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 16.)
|
||||||
<< "Result:\n" << rec << "\n"
|
<< "Result:\n"
|
||||||
<< "Residuals:\n" << error << "\n";
|
<< rec << "\n"
|
||||||
|
<< "Residuals:\n"
|
||||||
|
<< error << "\n";
|
||||||
|
|
||||||
// Reduce rank by duplicating one column
|
// Reduce rank by duplicating one column
|
||||||
i--;
|
i--;
|
||||||
|
|
@ -43,8 +46,9 @@ TTS_CASE_TPL("SVD decomposition - Dynamic case", rotgen::tests::types)
|
||||||
} while (rank != 1);
|
} while (rank != 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("SVD decomposition - Static case", rotgen::tests::types)
|
TTS_CASE_TPL("SVD decomposition - Static case",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
int rank, i = 5;
|
int rank, i = 5;
|
||||||
auto eps = std::numeric_limits<T>::epsilon();
|
auto eps = std::numeric_limits<T>::epsilon();
|
||||||
|
|
@ -52,8 +56,7 @@ TTS_CASE_TPL("SVD decomposition - Static case", rotgen::tests::types)
|
||||||
auto m = rotgen::matrix<T, 5, 5, O::value>::Random();
|
auto m = rotgen::matrix<T, 5, 5, O::value>::Random();
|
||||||
auto decomp = rotgen::svd(m);
|
auto decomp = rotgen::svd(m);
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
rank = decomp.rank();
|
rank = decomp.rank();
|
||||||
|
|
||||||
auto u = decomp.U(rank);
|
auto u = decomp.U(rank);
|
||||||
|
|
@ -67,8 +70,10 @@ TTS_CASE_TPL("SVD decomposition - Static case", rotgen::tests::types)
|
||||||
auto error = m - rec;
|
auto error = m - rec;
|
||||||
|
|
||||||
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 16.)
|
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 16.)
|
||||||
<< "Result:\n" << rec << "\n"
|
<< "Result:\n"
|
||||||
<< "Residuals:\n" << error << "\n";
|
<< rec << "\n"
|
||||||
|
<< "Residuals:\n"
|
||||||
|
<< error << "\n";
|
||||||
|
|
||||||
// Reduce rank by duplicating one column
|
// Reduce rank by duplicating one column
|
||||||
i--;
|
i--;
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,12 @@
|
||||||
#include "unit/common/arithmetic.hpp"
|
#include "unit/common/arithmetic.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic map transposition-like operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic map transposition-like operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_matrix_references();
|
auto const cases = rotgen::tests::generate_matrix_references();
|
||||||
for (const auto& [rows, cols, fn] : cases)
|
for (auto const& [rows, cols, fn] : cases)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
mat_t base(rows, cols);
|
mat_t base(rows, cols);
|
||||||
|
|
@ -24,59 +25,65 @@ TTS_CASE_TPL("Test dynamic map transposition-like operations", rotgen::tests::ty
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static map transposition-like operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test static map transposition-like operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_matrix_references();
|
auto const cases = rotgen::tests::generate_static_matrix_references();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& desc)
|
auto process = []<typename D>(D const& desc) {
|
||||||
{
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(D::rows,
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> base(D::rows,D::cols);
|
D::cols);
|
||||||
rotgen::tests::prepare(base.rows(), base.cols(), desc.init_fn, base);
|
rotgen::tests::prepare(base.rows(), base.cols(), desc.init_fn, base);
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,D::rows,D::cols,O::value>> input(base.data());
|
rotgen::map<rotgen::matrix<T, D::rows, D::cols, O::value>> input(
|
||||||
|
base.data());
|
||||||
rotgen::tests::check_shape_functions(input);
|
rotgen::tests::check_shape_functions(input);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic map reduction-like operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic map reduction-like operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_matrix_references();
|
auto const cases = rotgen::tests::generate_matrix_references();
|
||||||
for (const auto& [rows, cols, fn] : cases)
|
for (auto const& [rows, cols, fn] : cases)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> base(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(rows,
|
||||||
|
cols);
|
||||||
rotgen::tests::prepare(rows, cols, fn, base);
|
rotgen::tests::prepare(rows, cols, fn, base);
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>> input(base.data(),rows,cols);
|
rotgen::map<rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>>
|
||||||
|
input(base.data(), rows, cols);
|
||||||
rotgen::tests::check_reduction_functions(input);
|
rotgen::tests::check_reduction_functions(input);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static map reduction-like operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test static map reduction-like operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_matrix_references();
|
auto const cases = rotgen::tests::generate_static_matrix_references();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& desc)
|
auto process = []<typename D>(D const& desc) {
|
||||||
{
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(D::rows,
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> base(D::rows,D::cols);
|
D::cols);
|
||||||
rotgen::tests::prepare(base.rows(), base.cols(), desc.init_fn, base);
|
rotgen::tests::prepare(base.rows(), base.cols(), desc.init_fn, base);
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,D::rows,D::cols,O::value>> input(base.data());
|
rotgen::map<rotgen::matrix<T, D::rows, D::cols, O::value>> input(
|
||||||
|
base.data());
|
||||||
rotgen::tests::check_reduction_functions(input);
|
rotgen::tests::check_reduction_functions(input);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dot product", float, double)
|
TTS_CASE_TPL("Test dot product", float, double)<typename T>(tts::type<T>){
|
||||||
<typename T>( tts::type<T> )
|
{auto v = rotgen::setConstant<rotgen::matrix<T, 1, rotgen::Dynamic>>(1,
|
||||||
{
|
16,
|
||||||
{
|
2);
|
||||||
auto v = rotgen::setConstant<rotgen::matrix<T,1,rotgen::Dynamic>>(1,16,2);
|
|
||||||
auto a = rotgen::map<decltype(v)>(v.data(), 1, 8);
|
auto a = rotgen::map<decltype(v)>(v.data(), 1, 8);
|
||||||
auto b = rotgen::map<decltype(v)>(v.data() + 8, 1, 8);
|
auto b = rotgen::map<decltype(v)>(v.data() + 8, 1, 8);
|
||||||
|
|
||||||
|
|
@ -106,4 +113,5 @@ TTS_CASE_TPL("Test dot product", float, double)
|
||||||
|
|
||||||
TTS_EQUAL(rotgen::dot(a, b), 32);
|
TTS_EQUAL(rotgen::dot(a, b), 32);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
;
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,13 @@
|
||||||
#include "unit/tests.hpp"
|
#include "unit/tests.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Function size", rotgen::tests::types)
|
TTS_CASE_TPL("Function size", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>> dyn_map(data,1,12);
|
rotgen::map<rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>>
|
||||||
|
dyn_map(data, 1, 12);
|
||||||
TTS_EQUAL(dyn_map.rows(), rotgen::Index{1});
|
TTS_EQUAL(dyn_map.rows(), rotgen::Index{1});
|
||||||
TTS_EQUAL(dyn_map.cols(), rotgen::Index{12});
|
TTS_EQUAL(dyn_map.cols(), rotgen::Index{12});
|
||||||
|
|
||||||
|
|
@ -38,8 +39,9 @@ TTS_CASE_TPL("Function size", rotgen::tests::types)
|
||||||
TTS_EQUAL(s62_map.size(), rotgen::Index{12});
|
TTS_EQUAL(s62_map.size(), rotgen::Index{12});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
|
TTS_CASE_TPL("Test coefficient accessors",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using base = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using base = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
|
|
||||||
|
|
@ -63,13 +65,13 @@ TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
|
||||||
TTS_EQUAL(a(2, 2), 17);
|
TTS_EQUAL(a(2, 2), 17);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types)
|
TTS_CASE_TPL("Test one index coefficient accessors",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||||
|
|
||||||
auto m = [&]()
|
auto m = [&]() {
|
||||||
{
|
|
||||||
if constexpr (O::value == rotgen::ColMajor)
|
if constexpr (O::value == rotgen::ColMajor)
|
||||||
{
|
{
|
||||||
using base = rotgen::matrix<T, 1, rotgen::Dynamic>;
|
using base = rotgen::matrix<T, 1, rotgen::Dynamic>;
|
||||||
|
|
|
||||||
|
|
@ -8,30 +8,30 @@
|
||||||
#include "unit/tests.hpp"
|
#include "unit/tests.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("map constructor from pointer and single static size", rotgen::tests::types)
|
TTS_CASE_TPL("map constructor from pointer and single static size",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T, 1, 12, rotgen::RowMajor>> row_map(data);
|
rotgen::map<rotgen::matrix<T, 1, 12, rotgen::RowMajor>> row_map(data);
|
||||||
for(rotgen::Index i=0;i<12;i++)
|
for (rotgen::Index i = 0; i < 12; i++) TTS_EQUAL(row_map(i), data[i]);
|
||||||
TTS_EQUAL(row_map(i), data[i]);
|
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,1,12,rotgen::RowMajor> const> const_row_map(data);
|
rotgen::map<rotgen::matrix<T, 1, 12, rotgen::RowMajor> const> const_row_map(
|
||||||
for(rotgen::Index i=0;i<12;i++)
|
data);
|
||||||
TTS_EQUAL(const_row_map(i), data[i]);
|
for (rotgen::Index i = 0; i < 12; i++) TTS_EQUAL(const_row_map(i), data[i]);
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T, 12, 1, rotgen::ColMajor>> col_map(data);
|
rotgen::map<rotgen::matrix<T, 12, 1, rotgen::ColMajor>> col_map(data);
|
||||||
for(rotgen::Index i=0;i<12;i++)
|
for (rotgen::Index i = 0; i < 12; i++) TTS_EQUAL(col_map(i), data[i]);
|
||||||
TTS_EQUAL(col_map(i), data[i]);
|
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,12,1,rotgen::ColMajor> const> const_col_map(data);
|
rotgen::map<rotgen::matrix<T, 12, 1, rotgen::ColMajor> const> const_col_map(
|
||||||
for(rotgen::Index i=0;i<12;i++)
|
data);
|
||||||
TTS_EQUAL(const_col_map(i), data[i]);
|
for (rotgen::Index i = 0; i < 12; i++) TTS_EQUAL(const_col_map(i), data[i]);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("map constructor from pointer and static size", rotgen::tests::types)
|
TTS_CASE_TPL("map constructor from pointer and static size",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using base = rotgen::matrix<T, 4, 3, O::value>;
|
using base = rotgen::matrix<T, 4, 3, O::value>;
|
||||||
|
|
||||||
|
|
@ -48,30 +48,32 @@ TTS_CASE_TPL("map constructor from pointer and static size", rotgen::tests::type
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("map constructor from pointer and single dynamic size", rotgen::tests::types)
|
TTS_CASE_TPL("map constructor from pointer and single dynamic size",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,1,rotgen::Dynamic,rotgen::RowMajor>> row_map(data,12);
|
rotgen::map<rotgen::matrix<T, 1, rotgen::Dynamic, rotgen::RowMajor>> row_map(
|
||||||
for(rotgen::Index i=0;i<12;i++)
|
data, 12);
|
||||||
TTS_EQUAL(row_map(i), data[i]);
|
for (rotgen::Index i = 0; i < 12; i++) TTS_EQUAL(row_map(i), data[i]);
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,1,rotgen::Dynamic,rotgen::RowMajor> const> const_row_map(data,12);
|
rotgen::map<rotgen::matrix<T, 1, rotgen::Dynamic, rotgen::RowMajor> const>
|
||||||
for(rotgen::Index i=0;i<12;i++)
|
const_row_map(data, 12);
|
||||||
TTS_EQUAL(const_row_map(i), data[i]);
|
for (rotgen::Index i = 0; i < 12; i++) TTS_EQUAL(const_row_map(i), data[i]);
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,rotgen::Dynamic,1,rotgen::ColMajor>> col_map(data,12);
|
rotgen::map<rotgen::matrix<T, rotgen::Dynamic, 1, rotgen::ColMajor>> col_map(
|
||||||
for(rotgen::Index i=0;i<12;i++)
|
data, 12);
|
||||||
TTS_EQUAL(col_map(i), data[i]);
|
for (rotgen::Index i = 0; i < 12; i++) TTS_EQUAL(col_map(i), data[i]);
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,rotgen::Dynamic,1,rotgen::ColMajor> const> const_col_map(data,12);
|
rotgen::map<rotgen::matrix<T, rotgen::Dynamic, 1, rotgen::ColMajor> const>
|
||||||
for(rotgen::Index i=0;i<12;i++)
|
const_col_map(data, 12);
|
||||||
TTS_EQUAL(const_col_map(i), data[i]);
|
for (rotgen::Index i = 0; i < 12; i++) TTS_EQUAL(const_col_map(i), data[i]);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("map constructor from pointer and dynamic size", rotgen::tests::types)
|
TTS_CASE_TPL("map constructor from pointer and dynamic size",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using base = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using base = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,31 +9,36 @@
|
||||||
#include "unit/common/cwise.hpp"
|
#include "unit/common/cwise.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic map cwise operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic map cwise operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_matrix_references();
|
auto const cases = rotgen::tests::generate_matrix_references();
|
||||||
for (const auto& [rows, cols, fn] : cases)
|
for (auto const& [rows, cols, fn] : cases)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> base(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(rows,
|
||||||
|
cols);
|
||||||
rotgen::tests::prepare(rows, cols, fn, base);
|
rotgen::tests::prepare(rows, cols, fn, base);
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>> input(base.data(),rows,cols);
|
rotgen::map<rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>>
|
||||||
|
input(base.data(), rows, cols);
|
||||||
rotgen::tests::check_cwise_functions(input);
|
rotgen::tests::check_cwise_functions(input);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static map cwise operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test static map cwise operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_matrix_references();
|
auto const cases = rotgen::tests::generate_static_matrix_references();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& desc)
|
auto process = []<typename D>(D const& desc) {
|
||||||
{
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(D::rows,
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> base(D::rows,D::cols);
|
D::cols);
|
||||||
rotgen::tests::prepare(base.rows(), base.cols(), desc.init_fn, base);
|
rotgen::tests::prepare(base.rows(), base.cols(), desc.init_fn, base);
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,D::rows,D::cols,O::value>> input(base.data());
|
rotgen::map<rotgen::matrix<T, D::rows, D::cols, O::value>> input(
|
||||||
|
base.data());
|
||||||
rotgen::tests::check_cwise_functions(input);
|
rotgen::tests::check_cwise_functions(input);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,31 +9,36 @@
|
||||||
#include "unit/common/norms.hpp"
|
#include "unit/common/norms.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic map norm operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic map norm operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_matrix_references();
|
auto const cases = rotgen::tests::generate_matrix_references();
|
||||||
for (const auto& [rows, cols, fn] : cases)
|
for (auto const& [rows, cols, fn] : cases)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> base(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(rows,
|
||||||
|
cols);
|
||||||
rotgen::tests::prepare(rows, cols, fn, base);
|
rotgen::tests::prepare(rows, cols, fn, base);
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>> input(base.data(),rows,cols);
|
rotgen::map<rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>>
|
||||||
|
input(base.data(), rows, cols);
|
||||||
rotgen::tests::check_norms_functions(input);
|
rotgen::tests::check_norms_functions(input);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static map norm operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test static map norm operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_matrix_references();
|
auto const cases = rotgen::tests::generate_static_matrix_references();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& desc)
|
auto process = []<typename D>(D const& desc) {
|
||||||
{
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(D::rows,
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> base(D::rows,D::cols);
|
D::cols);
|
||||||
rotgen::tests::prepare(base.rows(), base.cols(), desc.init_fn, base);
|
rotgen::tests::prepare(base.rows(), base.cols(), desc.init_fn, base);
|
||||||
|
|
||||||
rotgen::map<rotgen::matrix<T,D::rows,D::cols,O::value>> input(base.data());
|
rotgen::map<rotgen::matrix<T, D::rows, D::cols, O::value>> input(
|
||||||
|
base.data());
|
||||||
rotgen::tests::check_norms_functions(input);
|
rotgen::tests::check_norms_functions(input);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,12 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
void test_map_operations(rotgen::Index rows, rotgen::Index cols, auto a_init_fn, auto b_init_fn, auto ops, auto self_ops)
|
void test_map_operations(rotgen::Index rows,
|
||||||
|
rotgen::Index cols,
|
||||||
|
auto a_init_fn,
|
||||||
|
auto b_init_fn,
|
||||||
|
auto ops,
|
||||||
|
auto self_ops)
|
||||||
{
|
{
|
||||||
MatrixType a_data(rows, cols);
|
MatrixType a_data(rows, cols);
|
||||||
MatrixType b_data(rows, cols);
|
MatrixType b_data(rows, cols);
|
||||||
|
|
@ -36,14 +41,18 @@ void test_map_operations(rotgen::Index rows, rotgen::Index cols, auto a_init_fn,
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
void test_map_scalar_operations(rotgen::Index rows, rotgen::Index cols, auto fn, auto s, auto ops, auto self_ops)
|
void test_map_scalar_operations(rotgen::Index rows,
|
||||||
|
rotgen::Index cols,
|
||||||
|
auto fn,
|
||||||
|
auto s,
|
||||||
|
auto ops,
|
||||||
|
auto self_ops)
|
||||||
{
|
{
|
||||||
MatrixType a_data(rows, cols);
|
MatrixType a_data(rows, cols);
|
||||||
MatrixType ref_data;
|
MatrixType ref_data;
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < rows; ++r)
|
for (rotgen::Index r = 0; r < rows; ++r)
|
||||||
for (rotgen::Index c = 0; c < cols; ++c)
|
for (rotgen::Index c = 0; c < cols; ++c) a_data(r, c) = fn(r, c);
|
||||||
a_data(r,c) = fn(r, c);
|
|
||||||
|
|
||||||
ref_data = ops(a_data, s);
|
ref_data = ops(a_data, s);
|
||||||
rotgen::map<MatrixType> a_map(a_data.data(), rows, cols);
|
rotgen::map<MatrixType> a_map(a_data.data(), rows, cols);
|
||||||
|
|
@ -57,14 +66,16 @@ void test_map_scalar_operations(rotgen::Index rows, rotgen::Index cols, auto fn,
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
void test_map_scalar_multiplications(rotgen::Index rows, rotgen::Index cols, auto fn, auto s)
|
void test_map_scalar_multiplications(rotgen::Index rows,
|
||||||
|
rotgen::Index cols,
|
||||||
|
auto fn,
|
||||||
|
auto s)
|
||||||
{
|
{
|
||||||
MatrixType a_data(rows, cols);
|
MatrixType a_data(rows, cols);
|
||||||
MatrixType ref_data;
|
MatrixType ref_data;
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < rows; ++r)
|
for (rotgen::Index r = 0; r < rows; ++r)
|
||||||
for (rotgen::Index c = 0; c < cols; ++c)
|
for (rotgen::Index c = 0; c < cols; ++c) a_data(r, c) = fn(r, c);
|
||||||
a_data(r,c) = fn(r, c);
|
|
||||||
|
|
||||||
ref_data = a_data * s;
|
ref_data = a_data * s;
|
||||||
rotgen::map<MatrixType> a_map(a_data.data(), rows, cols);
|
rotgen::map<MatrixType> a_map(a_data.data(), rows, cols);
|
||||||
|
|
@ -80,7 +91,10 @@ void test_map_scalar_multiplications(rotgen::Index rows, rotgen::Index cols, aut
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
void test_map_multiplication(rotgen::Index rows, rotgen::Index cols, auto a_init_fn, auto b_init_fn)
|
void test_map_multiplication(rotgen::Index rows,
|
||||||
|
rotgen::Index cols,
|
||||||
|
auto a_init_fn,
|
||||||
|
auto b_init_fn)
|
||||||
{
|
{
|
||||||
MatrixType a_data(rows, cols);
|
MatrixType a_data(rows, cols);
|
||||||
MatrixType b_data(cols, rows);
|
MatrixType b_data(cols, rows);
|
||||||
|
|
@ -106,15 +120,19 @@ void test_map_multiplication(rotgen::Index rows, rotgen::Index cols, auto a_init
|
||||||
TTS_EQUAL(a_map, ref_data);
|
TTS_EQUAL(a_map, ref_data);
|
||||||
TTS_EXPECT(verify_rotgen_reentrance(a_map *= b_map));
|
TTS_EXPECT(verify_rotgen_reentrance(a_map *= b_map));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline constexpr auto init_a = [](auto r, auto c) { return 9.9*r*r*r - 6*c - 12; };
|
inline constexpr auto init_a = [](auto r, auto c) {
|
||||||
inline constexpr auto init_b = [](auto r, auto c) { return 3.1*r + 4.2*c - 12.3; };
|
return 9.9 * r * r * r - 6 * c - 12;
|
||||||
|
};
|
||||||
|
inline constexpr auto init_b = [](auto r, auto c) {
|
||||||
|
return 3.1 * r + 4.2 * c - 12.3;
|
||||||
|
};
|
||||||
inline constexpr auto init_0 = [](auto, auto) { return 0; };
|
inline constexpr auto init_0 = [](auto, auto) { return 0; };
|
||||||
|
|
||||||
TTS_CASE_TPL("Check map addition", rotgen::tests::types)
|
TTS_CASE_TPL("Check map addition",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto op = [](auto a, auto b) { return a + b; };
|
auto op = [](auto a, auto b) { return a + b; };
|
||||||
|
|
@ -131,8 +149,9 @@ TTS_CASE_TPL("Check map addition", rotgen::tests::types)
|
||||||
test_map_operations<mat_t>(5, 5, init_a, init_0, op, s_op);
|
test_map_operations<mat_t>(5, 5, init_a, init_0, op, s_op);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check map subtraction", rotgen::tests::types)
|
TTS_CASE_TPL("Check map subtraction",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto op = [](auto a, auto b) { return a - b; };
|
auto op = [](auto a, auto b) { return a - b; };
|
||||||
|
|
@ -149,8 +168,9 @@ TTS_CASE_TPL("Check map subtraction", rotgen::tests::types)
|
||||||
test_map_operations<mat_t>(5, 5, init_a, init_0, op, s_op);
|
test_map_operations<mat_t>(5, 5, init_a, init_0, op, s_op);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check map multiplications", rotgen::tests::types)
|
TTS_CASE_TPL("Check map multiplications",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto init_id = [](auto r, auto c) { return r == c ? 1 : 0; };
|
auto init_id = [](auto r, auto c) { return r == c ? 1 : 0; };
|
||||||
|
|
@ -169,8 +189,9 @@ TTS_CASE_TPL("Check map multiplications", rotgen::tests::types)
|
||||||
test_map_multiplication<mat_t>(5, 5, init_a, init_0);
|
test_map_multiplication<mat_t>(5, 5, init_a, init_0);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check map multiplication with scalar", rotgen::tests::types)
|
TTS_CASE_TPL("Check map multiplication with scalar",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
|
|
||||||
|
|
@ -184,8 +205,9 @@ TTS_CASE_TPL("Check map multiplication with scalar", rotgen::tests::types)
|
||||||
test_map_scalar_multiplications<mat_t>(1, 10, init_a, T{-0.5});
|
test_map_scalar_multiplications<mat_t>(1, 10, init_a, T{-0.5});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check map division with scalar", rotgen::tests::types)
|
TTS_CASE_TPL("Check map division with scalar",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto op = [](auto a, auto b) { return a / b; };
|
auto op = [](auto a, auto b) { return a / b; };
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,10 @@ using r_mat_t = rotgen::matrix<float,rotgen::Dynamic,rotgen::Dynamic,O>;
|
||||||
template<int O>
|
template<int O>
|
||||||
using e_mat_t = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, O>;
|
using e_mat_t = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, O>;
|
||||||
|
|
||||||
template<typename M, typename S = rotgen::stride> using r_map_t = rotgen::map<M,0,S>;
|
template<typename M, typename S = rotgen::stride>
|
||||||
template<typename M, typename S = Eigen::Stride<0,0>> using e_map_t = Eigen::Map<M,0,S>;
|
using r_map_t = rotgen::map<M, 0, S>;
|
||||||
|
template<typename M, typename S = Eigen::Stride<0, 0>>
|
||||||
|
using e_map_t = Eigen::Map<M, 0, S>;
|
||||||
|
|
||||||
TTS_CASE("Validate Column Major Map with regular stride behavior")
|
TTS_CASE("Validate Column Major Map with regular stride behavior")
|
||||||
{
|
{
|
||||||
|
|
@ -53,14 +55,14 @@ TTS_CASE("Validate Column Major Map with specific outer stride behavior")
|
||||||
auto cols = 4;
|
auto cols = 4;
|
||||||
auto buffer = generate_data(rows, cols);
|
auto buffer = generate_data(rows, cols);
|
||||||
|
|
||||||
r_map_t<r_mat_t<rotgen::ColMajor>, rotgen::outer_stride<>>
|
r_map_t<r_mat_t<rotgen::ColMajor>, rotgen::outer_stride<>> r_map(
|
||||||
r_map(buffer.data(), rows, cols, rotgen::outer_stride(rows + 1));
|
buffer.data(), rows, cols, rotgen::outer_stride(rows + 1));
|
||||||
|
|
||||||
TTS_EQUAL(r_map.innerStride(), 1);
|
TTS_EQUAL(r_map.innerStride(), 1);
|
||||||
TTS_EQUAL(r_map.outerStride(), 4);
|
TTS_EQUAL(r_map.outerStride(), 4);
|
||||||
|
|
||||||
e_map_t<e_mat_t<Eigen::ColMajor>, Eigen::OuterStride<>>
|
e_map_t<e_mat_t<Eigen::ColMajor>, Eigen::OuterStride<>> e_map(
|
||||||
e_map(buffer.data(), rows, cols, Eigen::OuterStride<>(rows + 1));
|
buffer.data(), rows, cols, Eigen::OuterStride<>(rows + 1));
|
||||||
|
|
||||||
for (std::ptrdiff_t r = 0; r < rows; r++)
|
for (std::ptrdiff_t r = 0; r < rows; r++)
|
||||||
for (std::ptrdiff_t c = 0; c < cols; c++)
|
for (std::ptrdiff_t c = 0; c < cols; c++)
|
||||||
|
|
@ -73,14 +75,16 @@ TTS_CASE("Validate Column Major Map with specific inner stride behavior")
|
||||||
auto cols = 4;
|
auto cols = 4;
|
||||||
auto buffer = generate_data(rows, cols);
|
auto buffer = generate_data(rows, cols);
|
||||||
|
|
||||||
r_map_t<r_mat_t<rotgen::ColMajor>>
|
r_map_t<r_mat_t<rotgen::ColMajor>> r_map(buffer.data(), rows, cols,
|
||||||
r_map(buffer.data(), rows, cols, rotgen::stride(rows, 2));
|
rotgen::stride(rows, 2));
|
||||||
|
|
||||||
TTS_EQUAL(r_map.innerStride(), 2);
|
TTS_EQUAL(r_map.innerStride(), 2);
|
||||||
TTS_EQUAL(r_map.outerStride(), 3);
|
TTS_EQUAL(r_map.outerStride(), 3);
|
||||||
|
|
||||||
e_map_t<e_mat_t<Eigen::ColMajor>,Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>>
|
e_map_t<e_mat_t<Eigen::ColMajor>,
|
||||||
e_map(buffer.data(), rows, cols, Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>(rows,2));
|
Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>
|
||||||
|
e_map(buffer.data(), rows, cols,
|
||||||
|
Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>(rows, 2));
|
||||||
|
|
||||||
for (std::ptrdiff_t r = 0; r < rows; r++)
|
for (std::ptrdiff_t r = 0; r < rows; r++)
|
||||||
for (std::ptrdiff_t c = 0; c < cols; c++)
|
for (std::ptrdiff_t c = 0; c < cols; c++)
|
||||||
|
|
@ -111,14 +115,14 @@ TTS_CASE("Validate Row Major Map with specific outer stride behavior")
|
||||||
auto cols = 4;
|
auto cols = 4;
|
||||||
auto buffer = generate_data(rows, cols);
|
auto buffer = generate_data(rows, cols);
|
||||||
|
|
||||||
r_map_t<r_mat_t<rotgen::RowMajor>, rotgen::outer_stride<>>
|
r_map_t<r_mat_t<rotgen::RowMajor>, rotgen::outer_stride<>> r_map(
|
||||||
r_map(buffer.data(), rows, cols, rotgen::outer_stride(cols + 1));
|
buffer.data(), rows, cols, rotgen::outer_stride(cols + 1));
|
||||||
|
|
||||||
TTS_EQUAL(r_map.innerStride(), 1);
|
TTS_EQUAL(r_map.innerStride(), 1);
|
||||||
TTS_EQUAL(r_map.outerStride(), 5);
|
TTS_EQUAL(r_map.outerStride(), 5);
|
||||||
|
|
||||||
e_map_t<e_mat_t<Eigen::RowMajor>, Eigen::OuterStride<>>
|
e_map_t<e_mat_t<Eigen::RowMajor>, Eigen::OuterStride<>> e_map(
|
||||||
e_map(buffer.data(), rows, cols, Eigen::OuterStride<>(cols + 1));
|
buffer.data(), rows, cols, Eigen::OuterStride<>(cols + 1));
|
||||||
|
|
||||||
for (std::ptrdiff_t r = 0; r < rows; r++)
|
for (std::ptrdiff_t r = 0; r < rows; r++)
|
||||||
for (std::ptrdiff_t c = 0; c < cols; c++)
|
for (std::ptrdiff_t c = 0; c < cols; c++)
|
||||||
|
|
@ -131,14 +135,16 @@ TTS_CASE("Validate Row Major Map with specific inner stride behavior")
|
||||||
auto cols = 4;
|
auto cols = 4;
|
||||||
auto buffer = generate_data(rows, cols);
|
auto buffer = generate_data(rows, cols);
|
||||||
|
|
||||||
r_map_t<r_mat_t<rotgen::RowMajor>,rotgen::stride>
|
r_map_t<r_mat_t<rotgen::RowMajor>, rotgen::stride> r_map(
|
||||||
r_map(buffer.data(), rows, cols, rotgen::stride(2, cols));
|
buffer.data(), rows, cols, rotgen::stride(2, cols));
|
||||||
|
|
||||||
TTS_EQUAL(r_map.innerStride(), 4);
|
TTS_EQUAL(r_map.innerStride(), 4);
|
||||||
TTS_EQUAL(r_map.outerStride(), 2);
|
TTS_EQUAL(r_map.outerStride(), 2);
|
||||||
|
|
||||||
e_map_t<e_mat_t<Eigen::RowMajor>,Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>>
|
e_map_t<e_mat_t<Eigen::RowMajor>,
|
||||||
e_map(buffer.data(), rows, cols, Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>(2,cols));
|
Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>
|
||||||
|
e_map(buffer.data(), rows, cols,
|
||||||
|
Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>(2, cols));
|
||||||
|
|
||||||
for (std::ptrdiff_t r = 0; r < rows; r++)
|
for (std::ptrdiff_t r = 0; r < rows; r++)
|
||||||
for (std::ptrdiff_t c = 0; c < cols; c++)
|
for (std::ptrdiff_t c = 0; c < cols; c++)
|
||||||
|
|
|
||||||
|
|
@ -9,25 +9,27 @@
|
||||||
#include "unit/common/arithmetic.hpp"
|
#include "unit/common/arithmetic.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic matrix transposition-like operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic matrix transposition-like operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_matrix_references();
|
auto const cases = rotgen::tests::generate_matrix_references();
|
||||||
for (const auto& [rows, cols, fn] : cases)
|
for (auto const& [rows, cols, fn] : cases)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> input(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> input(rows,
|
||||||
|
cols);
|
||||||
rotgen::tests::prepare(rows, cols, fn, input);
|
rotgen::tests::prepare(rows, cols, fn, input);
|
||||||
rotgen::tests::check_shape_functions(input);
|
rotgen::tests::check_shape_functions(input);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static matrix transposition-like operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test static matrix transposition-like operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_matrix_references();
|
auto const cases = rotgen::tests::generate_static_matrix_references();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& desc)
|
auto process = []<typename D>(D const& desc) {
|
||||||
{
|
|
||||||
rotgen::matrix<T, D::rows, D::cols, O::value> input;
|
rotgen::matrix<T, D::rows, D::cols, O::value> input;
|
||||||
rotgen::tests::prepare(input.rows(), input.cols(), desc.init_fn, input);
|
rotgen::tests::prepare(input.rows(), input.cols(), desc.init_fn, input);
|
||||||
rotgen::tests::check_shape_functions(input);
|
rotgen::tests::check_shape_functions(input);
|
||||||
|
|
@ -36,25 +38,27 @@ TTS_CASE_TPL("Test static matrix transposition-like operations", rotgen::tests::
|
||||||
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic matrix reduction-like operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic matrix reduction-like operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_matrix_references();
|
auto const cases = rotgen::tests::generate_matrix_references();
|
||||||
for (const auto& [rows, cols, fn] : cases)
|
for (auto const& [rows, cols, fn] : cases)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> input(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> input(rows,
|
||||||
|
cols);
|
||||||
rotgen::tests::prepare(rows, cols, fn, input);
|
rotgen::tests::prepare(rows, cols, fn, input);
|
||||||
rotgen::tests::check_reduction_functions(input);
|
rotgen::tests::check_reduction_functions(input);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static matrix reduction-like operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test static matrix reduction-like operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_matrix_references();
|
auto const cases = rotgen::tests::generate_static_matrix_references();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& desc)
|
auto process = []<typename D>(D const& desc) {
|
||||||
{
|
|
||||||
rotgen::matrix<T, D::rows, D::cols, O::value> input;
|
rotgen::matrix<T, D::rows, D::cols, O::value> input;
|
||||||
rotgen::tests::prepare(input.rows(), input.cols(), desc.init_fn, input);
|
rotgen::tests::prepare(input.rows(), input.cols(), desc.init_fn, input);
|
||||||
rotgen::tests::check_reduction_functions(input);
|
rotgen::tests::check_reduction_functions(input);
|
||||||
|
|
@ -63,11 +67,8 @@ TTS_CASE_TPL("Test static matrix reduction-like operations", rotgen::tests::type
|
||||||
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dot product", float, double)
|
TTS_CASE_TPL("Test dot product", float, double)<typename T>(tts::type<T>){
|
||||||
<typename T>( tts::type<T> )
|
{auto a = rotgen::setConstant<rotgen::matrix<T, 1, rotgen::Dynamic>>(1, 8, 2);
|
||||||
{
|
|
||||||
{
|
|
||||||
auto a = rotgen::setConstant<rotgen::matrix<T,1,rotgen::Dynamic>>(1,8,2);
|
|
||||||
auto b = rotgen::setConstant<rotgen::matrix<T, 1, rotgen::Dynamic>>(1, 8, 2);
|
auto b = rotgen::setConstant<rotgen::matrix<T, 1, rotgen::Dynamic>>(1, 8, 2);
|
||||||
|
|
||||||
TTS_EQUAL(rotgen::dot(a, b), 32);
|
TTS_EQUAL(rotgen::dot(a, b), 32);
|
||||||
|
|
@ -93,4 +94,5 @@ TTS_CASE_TPL("Test dot product", float, double)
|
||||||
|
|
||||||
TTS_EQUAL(rotgen::dot(a, b), 32);
|
TTS_EQUAL(rotgen::dot(a, b), 32);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
;
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,15 @@
|
||||||
#include "unit/tests.hpp"
|
#include "unit/tests.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Function size", rotgen::tests::types)
|
TTS_CASE_TPL("Function size", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> empty_matrix;
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> empty_matrix;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix(3, 4);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix(3, 4);
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> row_vector(9,1);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> row_vector(9,
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> column_vector(1,5);
|
1);
|
||||||
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> column_vector(
|
||||||
|
1, 5);
|
||||||
|
|
||||||
TTS_EQUAL(empty_matrix.size(), rotgen::Index{0});
|
TTS_EQUAL(empty_matrix.size(), rotgen::Index{0});
|
||||||
TTS_EQUAL(matrix.size(), rotgen::Index{12});
|
TTS_EQUAL(matrix.size(), rotgen::Index{12});
|
||||||
|
|
@ -22,37 +24,36 @@ TTS_CASE_TPL("Function size", rotgen::tests::types)
|
||||||
TTS_EQUAL(column_vector.size(), rotgen::Index{5});
|
TTS_EQUAL(column_vector.size(), rotgen::Index{5});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Resizing dynamic matrix", rotgen::tests::types)
|
TTS_CASE_TPL("Resizing dynamic matrix",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(2, 3);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(2, 3);
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < a.rows(); ++r)
|
for (rotgen::Index r = 0; r < a.rows(); ++r)
|
||||||
for(rotgen::Index c=0;c<a.cols();++c)
|
for (rotgen::Index c = 0; c < a.cols(); ++c) a(r, c) = 42 + 2 * c + r;
|
||||||
a(r,c) = 42 + 2*c + r;
|
|
||||||
|
|
||||||
a.resize(3, 2);
|
a.resize(3, 2);
|
||||||
TTS_EQUAL(a.rows(), rotgen::Index(3));
|
TTS_EQUAL(a.rows(), rotgen::Index(3));
|
||||||
TTS_EQUAL(a.cols(), rotgen::Index(2));
|
TTS_EQUAL(a.cols(), rotgen::Index(2));
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < a.rows(); ++r)
|
for (rotgen::Index r = 0; r < a.rows(); ++r)
|
||||||
for(rotgen::Index c=0;c<a.cols();++c)
|
for (rotgen::Index c = 0; c < a.cols(); ++c) TTS_GREATER(a(r, c), 0);
|
||||||
TTS_GREATER(a(r,c),0);
|
|
||||||
|
|
||||||
a.resize(2, 2);
|
a.resize(2, 2);
|
||||||
TTS_EQUAL(a.rows(), rotgen::Index(2));
|
TTS_EQUAL(a.rows(), rotgen::Index(2));
|
||||||
TTS_EQUAL(a.cols(), rotgen::Index(2));
|
TTS_EQUAL(a.cols(), rotgen::Index(2));
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Dynamix matrix conservative resizing", rotgen::tests::types)
|
TTS_CASE_TPL("Dynamix matrix conservative resizing",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(2, 3);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(2, 3);
|
||||||
|
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for (rotgen::Index r = 0; r < a.rows(); ++r)
|
for (rotgen::Index r = 0; r < a.rows(); ++r)
|
||||||
for(rotgen::Index c=0;c<a.cols();++c)
|
for (rotgen::Index c = 0; c < a.cols(); ++c) a(r, c) = i++;
|
||||||
a(r, c) = i++;
|
|
||||||
|
|
||||||
a.conservativeResize(2, 3);
|
a.conservativeResize(2, 3);
|
||||||
TTS_EQUAL(a.rows(), rotgen::Index(2));
|
TTS_EQUAL(a.rows(), rotgen::Index(2));
|
||||||
|
|
@ -60,16 +61,14 @@ TTS_CASE_TPL("Dynamix matrix conservative resizing", rotgen::tests::types)
|
||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
for (rotgen::Index r = 0; r < a.rows(); ++r)
|
for (rotgen::Index r = 0; r < a.rows(); ++r)
|
||||||
for(rotgen::Index c=0;c<a.cols();++c)
|
for (rotgen::Index c = 0; c < a.cols(); ++c) TTS_EQUAL(a(r, c), i++);
|
||||||
TTS_EQUAL(a(r,c),i++);
|
|
||||||
|
|
||||||
a.conservativeResize(3, 2);
|
a.conservativeResize(3, 2);
|
||||||
TTS_EQUAL(a.rows(), rotgen::Index(3));
|
TTS_EQUAL(a.rows(), rotgen::Index(3));
|
||||||
TTS_EQUAL(a.cols(), rotgen::Index(2));
|
TTS_EQUAL(a.cols(), rotgen::Index(2));
|
||||||
int expected[3][2] = {{1, 2}, {4, 5}};
|
int expected[3][2] = {{1, 2}, {4, 5}};
|
||||||
for (rotgen::Index r = 0; r < 2; ++r)
|
for (rotgen::Index r = 0; r < 2; ++r)
|
||||||
for(rotgen::Index c = 0; c < 2; ++c)
|
for (rotgen::Index c = 0; c < 2; ++c) TTS_EQUAL(a(r, c), expected[r][c]);
|
||||||
TTS_EQUAL(a(r, c), expected[r][c]);
|
|
||||||
|
|
||||||
a.conservativeResize(4, 4);
|
a.conservativeResize(4, 4);
|
||||||
TTS_EQUAL(a.rows(), rotgen::Index(4));
|
TTS_EQUAL(a.rows(), rotgen::Index(4));
|
||||||
|
|
@ -98,14 +97,14 @@ TTS_CASE_TPL("Dynamix matrix conservative resizing", rotgen::tests::types)
|
||||||
TTS_EQUAL(a.cols(), rotgen::Index(3));
|
TTS_EQUAL(a.cols(), rotgen::Index(3));
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
|
TTS_CASE_TPL("Test coefficient accessors",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(3, 5);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(3, 5);
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < a.rows(); ++r)
|
for (rotgen::Index r = 0; r < a.rows(); ++r)
|
||||||
for(rotgen::Index c=0;c<a.cols();++c)
|
for (rotgen::Index c = 0; c < a.cols(); ++c) a(r, c) = r + 2 * c + 3;
|
||||||
a(r, c) = r + 2 * c + 3;
|
|
||||||
|
|
||||||
TTS_EQUAL(a(0, 0), 3);
|
TTS_EQUAL(a(0, 0), 3);
|
||||||
TTS_EQUAL(a(1, 1), 6);
|
TTS_EQUAL(a(1, 1), 6);
|
||||||
|
|
@ -121,27 +120,25 @@ TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
|
||||||
TTS_EQUAL(a(2, 2), 17);
|
TTS_EQUAL(a(2, 2), 17);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types)
|
TTS_CASE_TPL("Test one index coefficient accessors",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto a = [&]()
|
auto a = [&]() {
|
||||||
{
|
if constexpr (O::value == rotgen::ColMajor)
|
||||||
if constexpr(O::value == rotgen::ColMajor) return rotgen::matrix<T,1,rotgen::Dynamic>(1,8);
|
return rotgen::matrix<T, 1, rotgen::Dynamic>(1, 8);
|
||||||
else return rotgen::matrix<T, rotgen::Dynamic, 1>(8, 1);
|
else return rotgen::matrix<T, rotgen::Dynamic, 1>(8, 1);
|
||||||
}();
|
}();
|
||||||
|
|
||||||
TTS_EXPECT(a.IsVectorAtCompileTime);
|
TTS_EXPECT(a.IsVectorAtCompileTime);
|
||||||
|
|
||||||
for(rotgen::Index s=0;s<a.size();++s)
|
for (rotgen::Index s = 0; s < a.size(); ++s) a(s) = s + 1;
|
||||||
a(s) = s+1;
|
|
||||||
|
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for(rotgen::Index s=0;s<a.size();++s)
|
for (rotgen::Index s = 0; s < a.size(); ++s) TTS_EQUAL(a(s), i++) << a;
|
||||||
TTS_EQUAL(a(s), i++) << a;
|
|
||||||
|
|
||||||
i = 1;
|
i = 1;
|
||||||
for(rotgen::Index s=0;s<a.size();++s)
|
for (rotgen::Index s = 0; s < a.size(); ++s) TTS_EQUAL(a[s], i++) << a;
|
||||||
TTS_EQUAL(a[s], i++) << a;
|
|
||||||
|
|
||||||
T& ref = a(2);
|
T& ref = a(2);
|
||||||
ref = 999.5;
|
ref = 999.5;
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,9 @@
|
||||||
#include "unit/tests.hpp"
|
#include "unit/tests.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Default matrix dynamic constructor", rotgen::tests::types)
|
TTS_CASE_TPL("Default matrix dynamic constructor",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix;
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix;
|
||||||
|
|
||||||
|
|
@ -17,8 +18,9 @@ TTS_CASE_TPL("Default matrix dynamic constructor", rotgen::tests::types)
|
||||||
TTS_EQUAL(matrix.cols(), rotgen::Index{0});
|
TTS_EQUAL(matrix.cols(), rotgen::Index{0});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Default matrix static constructor", rotgen::tests::types)
|
TTS_CASE_TPL("Default matrix static constructor",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, 4, 9, O::value> matrix;
|
rotgen::matrix<T, 4, 9, O::value> matrix;
|
||||||
|
|
||||||
|
|
@ -26,8 +28,9 @@ TTS_CASE_TPL("Default matrix static constructor", rotgen::tests::types)
|
||||||
TTS_EQUAL(matrix.cols(), rotgen::Index{9});
|
TTS_EQUAL(matrix.cols(), rotgen::Index{9});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Dynamic matrix constructor with row and columns", rotgen::tests::types)
|
TTS_CASE_TPL("Dynamic matrix constructor with row and columns",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix(10, 5);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix(10, 5);
|
||||||
|
|
||||||
|
|
@ -35,8 +38,9 @@ TTS_CASE_TPL("Dynamic matrix constructor with row and columns", rotgen::tests::t
|
||||||
TTS_EQUAL(matrix.cols(), rotgen::Index{5});
|
TTS_EQUAL(matrix.cols(), rotgen::Index{5});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Static matrix constructor with row and columns", float, double)
|
TTS_CASE_TPL("Static matrix constructor with row and columns",
|
||||||
<typename T>( tts::type<T> )
|
float,
|
||||||
|
double)<typename T>(tts::type<T>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, 1, 2> v2(6, 11);
|
rotgen::matrix<T, 1, 2> v2(6, 11);
|
||||||
rotgen::matrix<T, 2, 1> w2(6, 11);
|
rotgen::matrix<T, 2, 1> w2(6, 11);
|
||||||
|
|
@ -59,14 +63,14 @@ TTS_CASE_TPL("Static matrix constructor with row and columns", float, double)
|
||||||
TTS_EQUAL(w3(2), T{125});
|
TTS_EQUAL(w3(2), T{125});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Copy constructor produces identical but independent matrix", rotgen::tests::types)
|
TTS_CASE_TPL("Copy constructor produces identical but independent matrix",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(3, 3);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(3, 3);
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < a.rows(); r++)
|
for (rotgen::Index r = 0; r < a.rows(); r++)
|
||||||
for(rotgen::Index c=0;c<a.cols();c++)
|
for (rotgen::Index c = 0; c < a.cols(); c++) a(r, c) = r + c;
|
||||||
a(r,c) = r + c;
|
|
||||||
|
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a;
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a;
|
||||||
|
|
||||||
|
|
@ -74,8 +78,7 @@ TTS_CASE_TPL("Copy constructor produces identical but independent matrix", rotge
|
||||||
TTS_EQUAL(b.cols(), a.cols());
|
TTS_EQUAL(b.cols(), a.cols());
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < a.rows(); r++)
|
for (rotgen::Index r = 0; r < a.rows(); r++)
|
||||||
for(rotgen::Index c=0;c<a.cols();c++)
|
for (rotgen::Index c = 0; c < a.cols(); c++) TTS_EQUAL(b(r, c), a(r, c));
|
||||||
TTS_EQUAL(b(r,c), a(r,c));
|
|
||||||
|
|
||||||
TTS_EQUAL(b(0, 0), 0.0);
|
TTS_EQUAL(b(0, 0), 0.0);
|
||||||
TTS_EQUAL(b(1, 0), 1.0);
|
TTS_EQUAL(b(1, 0), 1.0);
|
||||||
|
|
@ -85,8 +88,9 @@ TTS_CASE_TPL("Copy constructor produces identical but independent matrix", rotge
|
||||||
TTS_NOT_EQUAL(b(0, 0), a(0, 0));
|
TTS_NOT_EQUAL(b(0, 0), a(0, 0));
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Copy constructor on default matrix", rotgen::tests::types)
|
TTS_CASE_TPL("Copy constructor on default matrix",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a;
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a;
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a;
|
||||||
|
|
@ -94,17 +98,19 @@ TTS_CASE_TPL("Copy constructor on default matrix", rotgen::tests::types)
|
||||||
TTS_EQUAL(b.cols(), rotgen::Index{0});
|
TTS_EQUAL(b.cols(), rotgen::Index{0});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Copy constructor from const matrix", rotgen::tests::types)
|
TTS_CASE_TPL("Copy constructor from const matrix",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
const rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> a(2, 2);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> const a(2, 2);
|
||||||
auto b = a;
|
auto b = a;
|
||||||
TTS_EQUAL(b.rows(), rotgen::Index{2});
|
TTS_EQUAL(b.rows(), rotgen::Index{2});
|
||||||
TTS_EQUAL(b.cols(), rotgen::Index{2});
|
TTS_EQUAL(b.cols(), rotgen::Index{2});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Copy constructor on static matrix", rotgen::tests::types)
|
TTS_CASE_TPL("Copy constructor on static matrix",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, 2, 5> a;
|
rotgen::matrix<T, 2, 5> a;
|
||||||
rotgen::matrix<T, 2, 5> b = a;
|
rotgen::matrix<T, 2, 5> b = a;
|
||||||
|
|
@ -112,8 +118,9 @@ TTS_CASE_TPL("Copy constructor on static matrix", rotgen::tests::types)
|
||||||
TTS_EQUAL(b.cols(), rotgen::Index{5});
|
TTS_EQUAL(b.cols(), rotgen::Index{5});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Copy constructor on static/dynamic matrix", rotgen::tests::types)
|
TTS_CASE_TPL("Copy constructor on static/dynamic matrix",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, 11, 4, O::value> a;
|
rotgen::matrix<T, 11, 4, O::value> a;
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a;
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a;
|
||||||
|
|
@ -121,8 +128,9 @@ TTS_CASE_TPL("Copy constructor on static/dynamic matrix", rotgen::tests::types)
|
||||||
TTS_EQUAL(b.cols(), 4);
|
TTS_EQUAL(b.cols(), 4);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Copy constructor on dynamic/static matrix", rotgen::tests::types)
|
TTS_CASE_TPL("Copy constructor on dynamic/static matrix",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(5, 7);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(5, 7);
|
||||||
rotgen::matrix<T, 5, 7, O::value> b = a;
|
rotgen::matrix<T, 5, 7, O::value> b = a;
|
||||||
|
|
@ -130,14 +138,16 @@ TTS_CASE_TPL("Copy constructor on dynamic/static matrix", rotgen::tests::types)
|
||||||
TTS_EQUAL(b.cols(), 7);
|
TTS_EQUAL(b.cols(), 7);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Move constructor transfers contents", rotgen::tests::types)
|
TTS_CASE_TPL("Move constructor transfers contents",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(3, 3);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(3, 3);
|
||||||
a(1, 1) = 7;
|
a(1, 1) = 7;
|
||||||
auto ptr = a.data();
|
auto ptr = a.data();
|
||||||
|
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> b = std::move(a);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b =
|
||||||
|
std::move(a);
|
||||||
|
|
||||||
TTS_EQUAL(b(1, 1), 7);
|
TTS_EQUAL(b(1, 1), 7);
|
||||||
TTS_EQUAL(b.rows(), rotgen::Index{3});
|
TTS_EQUAL(b.rows(), rotgen::Index{3});
|
||||||
|
|
@ -145,16 +155,19 @@ TTS_CASE_TPL("Move constructor transfers contents", rotgen::tests::types)
|
||||||
TTS_EXPECT(b.data() == ptr);
|
TTS_EXPECT(b.data() == ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Move constructor from Rvalue", rotgen::tests::types)
|
TTS_CASE_TPL("Move constructor from Rvalue",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> b = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>(2, 2);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b =
|
||||||
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>(2, 2);
|
||||||
TTS_EQUAL(b.rows(), rotgen::Index{2});
|
TTS_EQUAL(b.rows(), rotgen::Index{2});
|
||||||
TTS_EQUAL(b.cols(), rotgen::Index{2});
|
TTS_EQUAL(b.cols(), rotgen::Index{2});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Constructor from Initializer list", rotgen::tests::types)
|
TTS_CASE_TPL("Constructor from Initializer list",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, 1, 1, O::value> b1{3.5};
|
rotgen::matrix<T, 1, 1, O::value> b1{3.5};
|
||||||
TTS_EQUAL(b1.rows(), rotgen::Index{1});
|
TTS_EQUAL(b1.rows(), rotgen::Index{1});
|
||||||
|
|
@ -180,18 +193,18 @@ TTS_CASE_TPL("Constructor from Initializer list", rotgen::tests::types)
|
||||||
TTS_EQUAL(b13(2), T(3.4));
|
TTS_EQUAL(b13(2), T(3.4));
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Constructor from Initializer list of rows", rotgen::tests::types)
|
TTS_CASE_TPL("Constructor from Initializer list of rows",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b1{{3.5}};
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b1{{3.5}};
|
||||||
TTS_EQUAL(b1.rows(), rotgen::Index{1});
|
TTS_EQUAL(b1.rows(), rotgen::Index{1});
|
||||||
TTS_EQUAL(b1.cols(), rotgen::Index{1});
|
TTS_EQUAL(b1.cols(), rotgen::Index{1});
|
||||||
TTS_EQUAL(b1(0, 0), T(3.5));
|
TTS_EQUAL(b1(0, 0), T(3.5));
|
||||||
|
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b23{
|
||||||
b23 { {1.2,2.3,3.4}
|
{1.2, 2.3, 3.4},
|
||||||
, {10,200,3000}
|
{10, 200, 3000}};
|
||||||
};
|
|
||||||
|
|
||||||
TTS_EQUAL(b23.rows(), rotgen::Index{2});
|
TTS_EQUAL(b23.rows(), rotgen::Index{2});
|
||||||
TTS_EQUAL(b23.cols(), rotgen::Index{3});
|
TTS_EQUAL(b23.cols(), rotgen::Index{3});
|
||||||
|
|
|
||||||
|
|
@ -9,25 +9,27 @@
|
||||||
#include "unit/common/cwise.hpp"
|
#include "unit/common/cwise.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic matrix cwise operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic matrix cwise operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_matrix_references();
|
auto const cases = rotgen::tests::generate_matrix_references();
|
||||||
for (const auto& [rows, cols, fn] : cases)
|
for (auto const& [rows, cols, fn] : cases)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> input(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> input(rows,
|
||||||
|
cols);
|
||||||
rotgen::tests::prepare(rows, cols, fn, input);
|
rotgen::tests::prepare(rows, cols, fn, input);
|
||||||
rotgen::tests::check_cwise_functions(input);
|
rotgen::tests::check_cwise_functions(input);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static matrix cwise operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test static matrix cwise operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_matrix_references();
|
auto const cases = rotgen::tests::generate_static_matrix_references();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& desc)
|
auto process = []<typename D>(D const& desc) {
|
||||||
{
|
|
||||||
rotgen::matrix<T, D::rows, D::cols, O::value> input;
|
rotgen::matrix<T, D::rows, D::cols, O::value> input;
|
||||||
rotgen::tests::prepare(input.rows(), input.cols(), desc.init_fn, input);
|
rotgen::tests::prepare(input.rows(), input.cols(), desc.init_fn, input);
|
||||||
rotgen::tests::check_cwise_functions(input);
|
rotgen::tests::check_cwise_functions(input);
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,17 @@
|
||||||
#include "unit/tests.hpp"
|
#include "unit/tests.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
void test_value(const auto& matrix, std::size_t rows, std::size_t cols, auto constant)
|
void test_value(auto const& matrix,
|
||||||
|
std::size_t rows,
|
||||||
|
std::size_t cols,
|
||||||
|
auto constant)
|
||||||
{
|
{
|
||||||
TTS_EXPECT(verify_rotgen_reentrance(matrix));
|
TTS_EXPECT(verify_rotgen_reentrance(matrix));
|
||||||
for (std::size_t r = 0; r < rows; ++r)
|
for (std::size_t r = 0; r < rows; ++r)
|
||||||
for(std::size_t c=0;c<cols;++c)
|
for (std::size_t c = 0; c < cols; ++c) TTS_EQUAL(matrix(r, c), constant);
|
||||||
TTS_EQUAL(matrix(r, c), constant);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_random(const auto& matrix, std::size_t rows, std::size_t cols)
|
void test_random(auto const& matrix, std::size_t rows, std::size_t cols)
|
||||||
{
|
{
|
||||||
TTS_EXPECT(verify_rotgen_reentrance(matrix));
|
TTS_EXPECT(verify_rotgen_reentrance(matrix));
|
||||||
for (std::size_t r = 0; r < rows; ++r)
|
for (std::size_t r = 0; r < rows; ++r)
|
||||||
|
|
@ -27,7 +29,7 @@ void test_random(const auto& matrix, std::size_t rows, std::size_t cols)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_identity(const auto& matrix, std::size_t rows, std::size_t cols)
|
void test_identity(auto const& matrix, std::size_t rows, std::size_t cols)
|
||||||
{
|
{
|
||||||
TTS_EXPECT(verify_rotgen_reentrance(matrix));
|
TTS_EXPECT(verify_rotgen_reentrance(matrix));
|
||||||
for (std::size_t r = 0; r < rows; ++r)
|
for (std::size_t r = 0; r < rows; ++r)
|
||||||
|
|
@ -35,8 +37,8 @@ void test_identity(const auto& matrix, std::size_t rows, std::size_t cols)
|
||||||
TTS_EQUAL(matrix(r, c), r == c ? 1 : 0);
|
TTS_EQUAL(matrix(r, c), r == c ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TTS_CASE_TPL("Test zero", rotgen::tests::types)
|
TTS_CASE_TPL("Test zero", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using namespace rotgen;
|
using namespace rotgen;
|
||||||
test_value(setZero<matrix<T, 3, 4, O::value>>(), 3, 4, 0);
|
test_value(setZero<matrix<T, 3, 4, O::value>>(), 3, 4, 0);
|
||||||
|
|
@ -56,8 +58,8 @@ TTS_CASE_TPL("Test zero", rotgen::tests::types)
|
||||||
test_value(setZero(matrix<T, Dynamic, 3>{2, 3}), 2, 3, 0);
|
test_value(setZero(matrix<T, Dynamic, 3>{2, 3}), 2, 3, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test ones", rotgen::tests::types)
|
TTS_CASE_TPL("Test ones", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using namespace rotgen;
|
using namespace rotgen;
|
||||||
test_value(setOnes<matrix<T, 3, 4, O::value>>(), 3, 4, 1);
|
test_value(setOnes<matrix<T, 3, 4, O::value>>(), 3, 4, 1);
|
||||||
|
|
@ -77,29 +79,34 @@ TTS_CASE_TPL("Test ones", rotgen::tests::types)
|
||||||
test_value(setOnes(matrix<T, Dynamic, 3>{2, 3}), 2, 3, 1);
|
test_value(setOnes(matrix<T, Dynamic, 3>{2, 3}), 2, 3, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test constant", rotgen::tests::types)
|
TTS_CASE_TPL("Test constant", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using namespace rotgen;
|
using namespace rotgen;
|
||||||
test_value(setConstant<matrix<T, 3, 4, O::value>>(T(5.12)), 3, 4, T(5.12));
|
test_value(setConstant<matrix<T, 3, 4, O::value>>(T(5.12)), 3, 4, T(5.12));
|
||||||
test_value(setConstant<matrix<T, 1, 1, O::value>>(T(5.12)), 1, 1, T(5.12));
|
test_value(setConstant<matrix<T, 1, 1, O::value>>(T(5.12)), 1, 1, T(5.12));
|
||||||
test_value(setConstant<matrix<T, 10, 10, O::value> >(T(5.12)), 10, 10, T(5.12));
|
test_value(setConstant<matrix<T, 10, 10, O::value>>(T(5.12)), 10, 10,
|
||||||
test_value(setConstant<matrix<T,Dynamic,Dynamic, O::value>>(3, 4, T(5.12)), 3, 4, T(5.12));
|
T(5.12));
|
||||||
test_value(setConstant<matrix<T, 7, 5, O::value> >(7, 5, T(5.12)), 7, 5, T(5.12));
|
test_value(setConstant<matrix<T, Dynamic, Dynamic, O::value>>(3, 4, T(5.12)),
|
||||||
|
3, 4, T(5.12));
|
||||||
|
test_value(setConstant<matrix<T, 7, 5, O::value>>(7, 5, T(5.12)), 7, 5,
|
||||||
|
T(5.12));
|
||||||
test_value(setConstant<matrix<T, 9, Dynamic>>(9, 3, T(5.12)), 9, 3, T(5.12));
|
test_value(setConstant<matrix<T, 9, Dynamic>>(9, 3, T(5.12)), 9, 3, T(5.12));
|
||||||
test_value(setConstant<matrix<T, Dynamic, 3>>(2, 3, T(5.12)), 2, 3, T(5.12));
|
test_value(setConstant<matrix<T, Dynamic, 3>>(2, 3, T(5.12)), 2, 3, T(5.12));
|
||||||
|
|
||||||
test_value(setConstant(matrix<T, 3, 4, O::value>{}, T(5.12)), 3, 4, T(5.12));
|
test_value(setConstant(matrix<T, 3, 4, O::value>{}, T(5.12)), 3, 4, T(5.12));
|
||||||
test_value(setConstant(matrix<T, 1, 1, O::value>{}, T(5.12)), 1, 1, T(5.12));
|
test_value(setConstant(matrix<T, 1, 1, O::value>{}, T(5.12)), 1, 1, T(5.12));
|
||||||
test_value(setConstant(matrix<T, 10, 10, O::value>{} , T(5.12)), 10, 10, T(5.12));
|
test_value(setConstant(matrix<T, 10, 10, O::value>{}, T(5.12)), 10, 10,
|
||||||
test_value(setConstant(matrix<T,Dynamic,Dynamic, O::value>{3, 4}, T(5.12)), 3, 4, T(5.12));
|
T(5.12));
|
||||||
|
test_value(setConstant(matrix<T, Dynamic, Dynamic, O::value>{3, 4}, T(5.12)),
|
||||||
|
3, 4, T(5.12));
|
||||||
test_value(setConstant(matrix<T, 7, 5, O::value>{}, T(5.12)), 7, 5, T(5.12));
|
test_value(setConstant(matrix<T, 7, 5, O::value>{}, T(5.12)), 7, 5, T(5.12));
|
||||||
test_value(setConstant(matrix<T, 9, Dynamic>{9, 3}, T(5.12)), 9, 3, T(5.12));
|
test_value(setConstant(matrix<T, 9, Dynamic>{9, 3}, T(5.12)), 9, 3, T(5.12));
|
||||||
test_value(setConstant(matrix<T, Dynamic, 3>{2, 3}, T(5.12)), 2, 3, T(5.12));
|
test_value(setConstant(matrix<T, Dynamic, 3>{2, 3}, T(5.12)), 2, 3, T(5.12));
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test random", rotgen::tests::types)
|
TTS_CASE_TPL("Test random", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using namespace rotgen;
|
using namespace rotgen;
|
||||||
test_random(setRandom<matrix<T, 3, 4, O::value>>(), 3, 4);
|
test_random(setRandom<matrix<T, 3, 4, O::value>>(), 3, 4);
|
||||||
|
|
@ -119,8 +126,8 @@ TTS_CASE_TPL("Test random", rotgen::tests::types)
|
||||||
test_random(setRandom(matrix<T, Dynamic, 3>{2, 3}), 2, 3);
|
test_random(setRandom(matrix<T, Dynamic, 3>{2, 3}), 2, 3);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test identity", rotgen::tests::types)
|
TTS_CASE_TPL("Test identity", rotgen::tests::types)<typename T, typename O>(
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using namespace rotgen;
|
using namespace rotgen;
|
||||||
test_identity(setIdentity<matrix<T, 3, 4, O::value>>(), 3, 4);
|
test_identity(setIdentity<matrix<T, 3, 4, O::value>>(), 3, 4);
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,15 @@
|
||||||
#include "unit/common/arithmetic.hpp"
|
#include "unit/common/arithmetic.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic matrix inverse", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic matrix inverse",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto eps = std::numeric_limits<T>::epsilon();
|
auto eps = std::numeric_limits<T>::epsilon();
|
||||||
|
|
||||||
auto const cases = rotgen::tests::generate_matrix_references();
|
auto const cases = rotgen::tests::generate_matrix_references();
|
||||||
for (const auto& [r, c, fn] : cases)
|
for (auto const& [r, c, fn] : cases)
|
||||||
{
|
{
|
||||||
if (r == c)
|
if (r == c)
|
||||||
{
|
{
|
||||||
|
|
@ -28,21 +29,23 @@ TTS_CASE_TPL("Test dynamic matrix inverse", rotgen::tests::types)
|
||||||
auto error = rec - id;
|
auto error = rec - id;
|
||||||
|
|
||||||
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 64.)
|
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 64.)
|
||||||
<< "Result:\n" << rec << "\n"
|
<< "Result:\n"
|
||||||
<< "Residuals:\n" << error << "\n";
|
<< rec << "\n"
|
||||||
|
<< "Residuals:\n"
|
||||||
|
<< error << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static matrix inverse", rotgen::tests::types)
|
TTS_CASE_TPL("Test static matrix inverse",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto eps = std::numeric_limits<T>::epsilon();
|
auto eps = std::numeric_limits<T>::epsilon();
|
||||||
auto const cases = rotgen::tests::generate_static_matrix_references();
|
auto const cases = rotgen::tests::generate_static_matrix_references();
|
||||||
|
|
||||||
auto process = [&]<typename D>(D const&)
|
auto process = [&]<typename D>(D const&) {
|
||||||
{
|
|
||||||
if constexpr (D::rows == D::cols)
|
if constexpr (D::rows == D::cols)
|
||||||
{
|
{
|
||||||
auto input = rotgen::matrix<T, D::rows, D::cols, O::value>::Random();
|
auto input = rotgen::matrix<T, D::rows, D::cols, O::value>::Random();
|
||||||
|
|
@ -53,8 +56,10 @@ TTS_CASE_TPL("Test static matrix inverse", rotgen::tests::types)
|
||||||
auto error = rec - id;
|
auto error = rec - id;
|
||||||
|
|
||||||
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 64.)
|
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 64.)
|
||||||
<< "Result:\n" << rec << "\n"
|
<< "Result:\n"
|
||||||
<< "Residuals:\n" << error << "\n";
|
<< rec << "\n"
|
||||||
|
<< "Residuals:\n"
|
||||||
|
<< error << "\n";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,25 +9,27 @@
|
||||||
#include "unit/common/norms.hpp"
|
#include "unit/common/norms.hpp"
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
TTS_CASE_TPL("Test dynamic matrix norm operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test dynamic matrix norm operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_matrix_references();
|
auto const cases = rotgen::tests::generate_matrix_references();
|
||||||
for (const auto& [rows, cols, fn] : cases)
|
for (auto const& [rows, cols, fn] : cases)
|
||||||
{
|
{
|
||||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> input(rows, cols);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> input(rows,
|
||||||
|
cols);
|
||||||
rotgen::tests::prepare(rows, cols, fn, input);
|
rotgen::tests::prepare(rows, cols, fn, input);
|
||||||
rotgen::tests::check_norms_functions(input);
|
rotgen::tests::check_norms_functions(input);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Test static matrix norm operations", rotgen::tests::types)
|
TTS_CASE_TPL("Test static matrix norm operations",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
auto const cases = rotgen::tests::generate_static_matrix_references();
|
auto const cases = rotgen::tests::generate_static_matrix_references();
|
||||||
|
|
||||||
auto process = []<typename D>(D const& desc)
|
auto process = []<typename D>(D const& desc) {
|
||||||
{
|
|
||||||
rotgen::matrix<T, D::rows, D::cols, O::value> input;
|
rotgen::matrix<T, D::rows, D::cols, O::value> input;
|
||||||
rotgen::tests::prepare(input.rows(), input.cols(), desc.init_fn, input);
|
rotgen::tests::prepare(input.rows(), input.cols(), desc.init_fn, input);
|
||||||
rotgen::tests::check_norms_functions(input);
|
rotgen::tests::check_norms_functions(input);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,12 @@
|
||||||
#include <rotgen/rotgen.hpp>
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
void test_matrix_operations(rotgen::Index rows, rotgen::Index cols, auto a_init_fn, auto b_init_fn, auto ops, auto self_ops)
|
void test_matrix_operations(rotgen::Index rows,
|
||||||
|
rotgen::Index cols,
|
||||||
|
auto a_init_fn,
|
||||||
|
auto b_init_fn,
|
||||||
|
auto ops,
|
||||||
|
auto self_ops)
|
||||||
{
|
{
|
||||||
MatrixType a(rows, cols);
|
MatrixType a(rows, cols);
|
||||||
MatrixType b(rows, cols);
|
MatrixType b(rows, cols);
|
||||||
|
|
@ -34,7 +39,12 @@ void test_matrix_operations(rotgen::Index rows, rotgen::Index cols, auto a_init_
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
void test_scalar_operations(rotgen::Index rows, rotgen::Index cols, auto a_init_fn, auto s, auto ops, auto self_ops)
|
void test_scalar_operations(rotgen::Index rows,
|
||||||
|
rotgen::Index cols,
|
||||||
|
auto a_init_fn,
|
||||||
|
auto s,
|
||||||
|
auto ops,
|
||||||
|
auto self_ops)
|
||||||
{
|
{
|
||||||
MatrixType a(rows, cols);
|
MatrixType a(rows, cols);
|
||||||
MatrixType ref(rows, cols);
|
MatrixType ref(rows, cols);
|
||||||
|
|
@ -57,7 +67,10 @@ void test_scalar_operations(rotgen::Index rows, rotgen::Index cols, auto a_init_
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
void test_scalar_multiplications(rotgen::Index rows, rotgen::Index cols, auto fn, auto s)
|
void test_scalar_multiplications(rotgen::Index rows,
|
||||||
|
rotgen::Index cols,
|
||||||
|
auto fn,
|
||||||
|
auto s)
|
||||||
{
|
{
|
||||||
MatrixType a(rows, cols);
|
MatrixType a(rows, cols);
|
||||||
MatrixType ref(rows, cols);
|
MatrixType ref(rows, cols);
|
||||||
|
|
@ -82,19 +95,20 @@ void test_scalar_multiplications(rotgen::Index rows, rotgen::Index cols, auto fn
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
void test_matrix_multiplication(rotgen::Index rows, rotgen::Index cols, auto a_init_fn, auto b_init_fn)
|
void test_matrix_multiplication(rotgen::Index rows,
|
||||||
|
rotgen::Index cols,
|
||||||
|
auto a_init_fn,
|
||||||
|
auto b_init_fn)
|
||||||
{
|
{
|
||||||
MatrixType a(rows, cols);
|
MatrixType a(rows, cols);
|
||||||
MatrixType b(cols, rows);
|
MatrixType b(cols, rows);
|
||||||
MatrixType ref(rows, rows);
|
MatrixType ref(rows, rows);
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < a.rows(); ++r)
|
for (rotgen::Index r = 0; r < a.rows(); ++r)
|
||||||
for (rotgen::Index c = 0; c < a.cols(); ++c)
|
for (rotgen::Index c = 0; c < a.cols(); ++c) a(r, c) = a_init_fn(r, c);
|
||||||
a(r,c) = a_init_fn(r, c);
|
|
||||||
|
|
||||||
for (rotgen::Index r = 0; r < b.rows(); ++r)
|
for (rotgen::Index r = 0; r < b.rows(); ++r)
|
||||||
for (rotgen::Index c = 0; c < b.cols(); ++c)
|
for (rotgen::Index c = 0; c < b.cols(); ++c) b(r, c) = b_init_fn(r, c);
|
||||||
b(r,c) = b_init_fn(r, c);
|
|
||||||
|
|
||||||
for (rotgen::Index i = 0; i < a.rows(); ++i)
|
for (rotgen::Index i = 0; i < a.rows(); ++i)
|
||||||
{
|
{
|
||||||
|
|
@ -111,12 +125,17 @@ void test_matrix_multiplication(rotgen::Index rows, rotgen::Index cols, auto a_i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basic initializers
|
// Basic initializers
|
||||||
inline constexpr auto init_a = [](auto r, auto c) { return 9.9*r*r*r - 6*c -12; };
|
inline constexpr auto init_a = [](auto r, auto c) {
|
||||||
inline constexpr auto init_b = [](auto r, auto c) { return 3.1*r + 4.2*c - 12.3; };
|
return 9.9 * r * r * r - 6 * c - 12;
|
||||||
|
};
|
||||||
|
inline constexpr auto init_b = [](auto r, auto c) {
|
||||||
|
return 3.1 * r + 4.2 * c - 12.3;
|
||||||
|
};
|
||||||
inline constexpr auto init_0 = [](auto, auto) { return 0; };
|
inline constexpr auto init_0 = [](auto, auto) { return 0; };
|
||||||
|
|
||||||
TTS_CASE_TPL("Check matrix addition", rotgen::tests::types)
|
TTS_CASE_TPL("Check matrix addition",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto op = [](auto a, auto b) { return a + b; };
|
auto op = [](auto a, auto b) { return a + b; };
|
||||||
|
|
@ -133,8 +152,9 @@ TTS_CASE_TPL("Check matrix addition", rotgen::tests::types)
|
||||||
test_matrix_operations<mat_t>(5, 5, init_a, init_0, op, s_op);
|
test_matrix_operations<mat_t>(5, 5, init_a, init_0, op, s_op);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check matrix substraction", rotgen::tests::types)
|
TTS_CASE_TPL("Check matrix substraction",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto op = [](auto a, auto b) { return a - b; };
|
auto op = [](auto a, auto b) { return a - b; };
|
||||||
|
|
@ -151,8 +171,9 @@ TTS_CASE_TPL("Check matrix substraction", rotgen::tests::types)
|
||||||
test_matrix_operations<mat_t>(5, 5, init_a, init_0, op, s_op);
|
test_matrix_operations<mat_t>(5, 5, init_a, init_0, op, s_op);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check matrix multiplications", rotgen::tests::types)
|
TTS_CASE_TPL("Check matrix multiplications",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto init_id = [](auto r, auto c) { return r == c ? 1 : 0; };
|
auto init_id = [](auto r, auto c) { return r == c ? 1 : 0; };
|
||||||
|
|
@ -171,8 +192,9 @@ TTS_CASE_TPL("Check matrix multiplications", rotgen::tests::types)
|
||||||
test_matrix_multiplication<mat_t>(5, 5, init_a, init_0);
|
test_matrix_multiplication<mat_t>(5, 5, init_a, init_0);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check matrix multiplication with scalar", rotgen::tests::types)
|
TTS_CASE_TPL("Check matrix multiplication with scalar",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
|
|
||||||
|
|
@ -186,8 +208,9 @@ TTS_CASE_TPL("Check matrix multiplication with scalar", rotgen::tests::types)
|
||||||
test_scalar_multiplications<mat_t>(1, 10, init_a, T{-0.5});
|
test_scalar_multiplications<mat_t>(1, 10, init_a, T{-0.5});
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("Check matrix division with scalar", rotgen::tests::types)
|
TTS_CASE_TPL("Check matrix division with scalar",
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
rotgen::tests::types)<typename T, typename O>(
|
||||||
|
tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||||
auto op = [](auto a, auto b) { return a / b; };
|
auto op = [](auto a, auto b) { return a / b; };
|
||||||
|
|
|
||||||
|
|
@ -15,22 +15,23 @@
|
||||||
|
|
||||||
namespace rotgen::tests
|
namespace rotgen::tests
|
||||||
{
|
{
|
||||||
template<auto N> struct constant { static constexpr auto value = N; };
|
template<auto N> struct constant
|
||||||
|
{
|
||||||
|
static constexpr auto value = N;
|
||||||
|
};
|
||||||
|
|
||||||
using scalar = tts::types<float, double>;
|
using scalar = tts::types<float, double>;
|
||||||
using order = tts::types<constant<ColMajor>, constant<RowMajor>>;
|
using order = tts::types<constant<ColMajor>, constant<RowMajor>>;
|
||||||
|
|
||||||
using types = tts::types< tts::types<float ,constant<ColMajor>>
|
using types = tts::types<tts::types<float, constant<ColMajor>>,
|
||||||
, tts::types<double,constant<ColMajor>>
|
tts::types<double, constant<ColMajor>>,
|
||||||
, tts::types<float ,constant<RowMajor>>
|
tts::types<float, constant<RowMajor>>,
|
||||||
, tts::types<double,constant<RowMajor>>
|
tts::types<double, constant<RowMajor>>>;
|
||||||
>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
template<typename T>
|
template<typename T> constexpr bool verify_rotgen_reentrance(T const&)
|
||||||
constexpr bool verify_rotgen_reentrance(T const&)
|
|
||||||
{
|
{
|
||||||
if constexpr (rotgen::use_expression_templates) return true;
|
if constexpr (rotgen::use_expression_templates) return true;
|
||||||
else return rotgen::concepts::entity<T>;
|
else return rotgen::concepts::entity<T>;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue