Merged develop into feature/MatrixPrinting
commit
1d44761e3c
400
.cproject
400
.cproject
|
|
@ -1,19 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?>
|
||||
|
||||
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="cdt.managedbuild.toolchain.gnu.macosx.base.1359703544">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.macosx.base.1359703544" moduleId="org.eclipse.cdt.core.settings" name="MacOSX GCC">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
|
@ -62,13 +60,13 @@
|
|||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.macosx.base.1359703544.1441575890" moduleId="org.eclipse.cdt.core.settings" name="Timing">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
|
@ -118,13 +116,13 @@
|
|||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.macosx.base.1359703544.127261216" moduleId="org.eclipse.cdt.core.settings" name="fast">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
|
@ -510,30 +508,6 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testInvDepthCamera3.run" path="build/gtsam_unstable/geometry/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testInvDepthCamera3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testTriangulation.run" path="build/gtsam_unstable/geometry/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testTriangulation.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testEvent.run" path="build/gtsam_unstable/geometry/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testEvent.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
|
@ -558,6 +532,38 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testSimilarity3.run" path="build/gtsam_unstable/geometry/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testSimilarity3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testInvDepthCamera3.run" path="build/gtsam_unstable/geometry/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testInvDepthCamera3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testTriangulation.run" path="build/gtsam_unstable/geometry/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testTriangulation.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testEvent.run" path="build/gtsam_unstable/geometry/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testEvent.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="all" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
|
@ -1334,46 +1340,6 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testBTree.run" path="build/gtsam_unstable/base/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testBTree.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testDSF.run" path="build/gtsam_unstable/base/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testDSF.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testDSFMap.run" path="build/gtsam_unstable/base/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testDSFMap.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testDSFVector.run" path="build/gtsam_unstable/base/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testDSFVector.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testFixedVector.run" path="build/gtsam_unstable/base/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testFixedVector.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="all" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
|
@ -1515,6 +1481,46 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testBTree.run" path="build/gtsam_unstable/base/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testBTree.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testDSF.run" path="build/gtsam_unstable/base/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testDSF.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testDSFMap.run" path="build/gtsam_unstable/base/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testDSFMap.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testDSFVector.run" path="build/gtsam_unstable/base/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testDSFVector.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testFixedVector.run" path="build/gtsam_unstable/base/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testFixedVector.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testEliminationTree.run" path="build/gtsam/inference/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
|
|
@ -1986,6 +1992,14 @@
|
|||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check.sam" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>check.sam</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
|
@ -2185,6 +2199,46 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testOrientedPlane3.run" path="build/gtsam/geometry/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testOrientedPlane3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testPinholePose.run" path="build/gtsam/geometry/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testPinholePose.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testCyclic.run" path="build/gtsam/geometry/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testCyclic.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testUnit3.run" path="build/gtsam/geometry/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testUnit3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testBearingRange.run" path="build/gtsam/geometry/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testBearingRange.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="all" path="release" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
|
@ -2265,38 +2319,6 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testIMUSystem.run" path="build/gtsam_unstable/dynamics/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testIMUSystem.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testPoseRTV.run" path="build/gtsam_unstable/dynamics/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testPoseRTV.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testVelocityConstraint.run" path="build/gtsam_unstable/dynamics/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testVelocityConstraint.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testVelocityConstraint3.run" path="build/gtsam_unstable/dynamics/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testVelocityConstraint3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testDiscreteBayesTree.run" path="build/gtsam/discrete/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j1</buildArguments>
|
||||
|
|
@ -2337,6 +2359,38 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testIMUSystem.run" path="build/gtsam_unstable/dynamics/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testIMUSystem.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testPoseRTV.run" path="build/gtsam_unstable/dynamics/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testPoseRTV.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testVelocityConstraint.run" path="build/gtsam_unstable/dynamics/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testVelocityConstraint.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testVelocityConstraint3.run" path="build/gtsam_unstable/dynamics/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testVelocityConstraint3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
|
@ -2553,6 +2607,14 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGroup.run" path="build/gtsam/base/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testGroup.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check.tests" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
|
|
@ -2777,6 +2839,22 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testLie.run" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testLie.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testSerializationSLAM.run" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testSerializationSLAM.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testParticleFactor.run" path="build/gtsam_unstable/nonlinear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
|
|
@ -2785,22 +2863,6 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testExpressionMeta.run" path="build/gtsam_unstable/nonlinear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
<buildTarget>testExpressionMeta.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testCustomChartExpression.run" path="build/gtsam_unstable/nonlinear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testCustomChartExpression.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianFactor.run" path="build/linear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
|
@ -2937,10 +2999,26 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testRangeFactor.run" path="build/gtsam/slam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="testOrientedPlane3Factor.run" path="build/gtsam/slam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testRangeFactor.run</buildTarget>
|
||||
<buildTarget>testOrientedPlane3Factor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testSmartProjectionPoseFactor.run" path="build/gtsam/slam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testSmartProjectionPoseFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testInitializePose3.run" path="build/gtsam/slam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testInitializePose3.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
|
|
@ -3137,6 +3215,14 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="SFMExampleExpressions_bal.run" path="build/examples" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>SFMExampleExpressions_bal.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testLago.run" path="build/gtsam/nonlinear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
|
|
@ -3209,6 +3295,22 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testExecutionTrace.run" path="build/gtsam/nonlinear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testExecutionTrace.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testSerializationNonlinear.run" path="build/gtsam/nonlinear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testSerializationNonlinear.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testImuFactor.run" path="build-debug/gtsam_unstable/slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
|
|
@ -3217,6 +3319,21 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>check</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testGaussianISAM2" path="build/slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildTarget>tests/testGaussianISAM2</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="timeCalibratedCamera.run" path="build/timing" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
|
|
@ -3297,19 +3414,20 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="timeSchurFactors.run" path="build/timing" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>check</buildTarget>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>timeSchurFactors.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testGaussianISAM2" path="build/slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<target name="timeRot2.run" path="build/timing" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildTarget>tests/testGaussianISAM2</buildTarget>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>timeRot2.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testRot3.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
|
|
@ -3408,6 +3526,30 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testBearingFactor.run" path="build/gtsam/sam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testBearingFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testRangeFactor.run" path="build/gtsam/sam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testRangeFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testBearingRangeFactor.run" path="build/gtsam/sam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j4</buildArguments>
|
||||
<buildTarget>testBearingRangeFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="wrap" path="build/wrap" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j5</buildArguments>
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
/org.eclipse.cdt.codan.core.prefs
|
||||
|
|
@ -158,6 +158,12 @@ else()
|
|||
set(GTSAM_USE_TBB 0) # This will go into config.h
|
||||
endif()
|
||||
|
||||
###############################################################################
|
||||
# Prohibit Timing build mode in combination with TBB
|
||||
if(GTSAM_USE_TBB AND (CMAKE_BUILD_TYPE STREQUAL "Timing"))
|
||||
message(FATAL_ERROR "Timing build mode cannot be used together with TBB. Use a sampling profiler such as Instruments or Intel VTune Amplifier instead.")
|
||||
endif()
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Find Google perftools
|
||||
|
|
@ -173,6 +179,11 @@ if(MKL_FOUND AND GTSAM_WITH_EIGEN_MKL)
|
|||
set(EIGEN_USE_MKL_ALL 1) # This will go into config.h - it makes Eigen use MKL
|
||||
include_directories(${MKL_INCLUDE_DIR})
|
||||
list(APPEND GTSAM_ADDITIONAL_LIBRARIES ${MKL_LIBRARIES})
|
||||
|
||||
# --no-as-needed is required with gcc according to the MKL link advisor
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-as-needed")
|
||||
endif()
|
||||
else()
|
||||
set(GTSAM_USE_EIGEN_MKL 0)
|
||||
set(EIGEN_USE_MKL_ALL 0)
|
||||
|
|
@ -192,36 +203,40 @@ endif()
|
|||
|
||||
###############################################################################
|
||||
# Option for using system Eigen or GTSAM-bundled Eigen
|
||||
### Disabled until our patches are included in Eigen ###
|
||||
### These patches only affect usage of MKL. If you want to enable MKL, you *must*
|
||||
### use our patched version of Eigen
|
||||
### See: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=704 (Householder QR MKL selection)
|
||||
### http://eigen.tuxfamily.org/bz/show_bug.cgi?id=705 (Fix MKL LLT return code)
|
||||
### http://eigen.tuxfamily.org/bz/show_bug.cgi?id=716 (Improved comma initialization)
|
||||
# option(GTSAM_USE_SYSTEM_EIGEN "Find and use system-installed Eigen. If 'off', use the one bundled with GTSAM" OFF)
|
||||
set(GTSAM_USE_SYSTEM_EIGEN OFF)
|
||||
option(GTSAM_USE_SYSTEM_EIGEN "Find and use system-installed Eigen. If 'off', use the one bundled with GTSAM" OFF)
|
||||
|
||||
# Switch for using system Eigen or GTSAM-bundled Eigen
|
||||
if(GTSAM_USE_SYSTEM_EIGEN)
|
||||
# Use generic Eigen include paths e.g. <Eigen/Core>
|
||||
set(GTSAM_EIGEN_INCLUDE_PREFIX "")
|
||||
|
||||
find_package(Eigen3 REQUIRED)
|
||||
include_directories(AFTER "${EIGEN3_INCLUDE_DIR}")
|
||||
|
||||
# Use generic Eigen include paths e.g. <Eigen/Core>
|
||||
set(GTSAM_EIGEN_INCLUDE_PREFIX "${EIGEN3_INCLUDE_DIR}")
|
||||
|
||||
# check if MKL is also enabled - can have one or the other, but not both!
|
||||
if(EIGEN_USE_MKL_ALL)
|
||||
message(FATAL_ERROR "MKL cannot be used together with system-installed Eigen, as MKL support relies on patches which are not yet in the system-installed Eigen. Disable either GTSAM_USE_SYSTEM_EIGEN or GTSAM_WITH_EIGEN_MKL")
|
||||
endif()
|
||||
else()
|
||||
# Use bundled Eigen include paths e.g. <gtsam/3rdparty/Eigen/Eigen/Core>
|
||||
set(GTSAM_EIGEN_INCLUDE_PREFIX "gtsam/3rdparty/Eigen/")
|
||||
|
||||
# Use bundled Eigen include path.
|
||||
# Clear any variables set by FindEigen3
|
||||
if(EIGEN3_INCLUDE_DIR)
|
||||
set(EIGEN3_INCLUDE_DIR NOTFOUND CACHE STRING "" FORCE)
|
||||
endif()
|
||||
# Add the bundled version of eigen to the include path so that it can still be included
|
||||
# with #include <Eigen/Core>
|
||||
include_directories(BEFORE "gtsam/3rdparty/Eigen/")
|
||||
|
||||
# set full path to be used by external projects
|
||||
# this will be added to GTSAM_INCLUDE_DIR by gtsam_extra.cmake.in
|
||||
set(GTSAM_EIGEN_INCLUDE_PREFIX "${CMAKE_INSTALL_PREFIX}/include/gtsam/3rdparty/Eigen/")
|
||||
|
||||
endif()
|
||||
|
||||
# Write Eigen include file with the paths for either the system Eigen or the GTSAM-bundled Eigen
|
||||
configure_file(gtsam/3rdparty/gtsam_eigen_includes.h.in gtsam/3rdparty/gtsam_eigen_includes.h)
|
||||
|
||||
# Install the configuration file for Eigen
|
||||
install(FILES ${PROJECT_BINARY_DIR}/gtsam/3rdparty/gtsam_eigen_includes.h DESTINATION include/gtsam/3rdparty)
|
||||
|
||||
###############################################################################
|
||||
# Global compile options
|
||||
|
||||
|
|
@ -262,7 +277,8 @@ endif()
|
|||
|
||||
# Include boost - use 'BEFORE' so that a specific boost specified to CMake
|
||||
# takes precedence over a system-installed one.
|
||||
include_directories(BEFORE ${Boost_INCLUDE_DIR})
|
||||
# Use 'SYSTEM' to ignore compiler warnings in Boost headers
|
||||
include_directories(BEFORE SYSTEM ${Boost_INCLUDE_DIR})
|
||||
|
||||
# Add includes for source directories 'BEFORE' boost and any system include
|
||||
# paths so that the compiler uses GTSAM headers in our source directory instead
|
||||
|
|
@ -289,6 +305,13 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|||
endif()
|
||||
endif()
|
||||
|
||||
# As of XCode 7, clang also complains about this
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)
|
||||
add_definitions(-Wno-unused-local-typedefs)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(GTSAM_ENABLE_CONSISTENCY_CHECKS)
|
||||
add_definitions(-DGTSAM_EXTRA_CONSISTENCY_CHECKS)
|
||||
endif()
|
||||
|
|
@ -371,6 +394,8 @@ set(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-dev (>= 1.43)") #Example: "libc6 (>=
|
|||
# Print configuration variables
|
||||
message(STATUS "===============================================================")
|
||||
message(STATUS "================ Configuration Options ======================")
|
||||
message(STATUS " CMAKE_CXX_COMPILER_ID type : ${CMAKE_CXX_COMPILER_ID}")
|
||||
message(STATUS " CMAKE_CXX_COMPILER_VERSION : ${CMAKE_CXX_COMPILER_VERSION}")
|
||||
message(STATUS "Build flags ")
|
||||
print_config_flag(${GTSAM_BUILD_TESTS} "Build Tests ")
|
||||
print_config_flag(${GTSAM_BUILD_EXAMPLES_ALWAYS} "Build examples with 'make all' ")
|
||||
|
|
@ -389,6 +414,11 @@ if(NOT MSVC AND NOT XCODE_VERSION)
|
|||
message(STATUS " C compilation flags : ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${cmake_build_type_toupper}}")
|
||||
message(STATUS " C++ compilation flags : ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${cmake_build_type_toupper}}")
|
||||
endif()
|
||||
if(GTSAM_USE_SYSTEM_EIGEN)
|
||||
message(STATUS " Use System Eigen : Yes")
|
||||
else()
|
||||
message(STATUS " Use System Eigen : No")
|
||||
endif()
|
||||
if(GTSAM_USE_TBB)
|
||||
message(STATUS " Use Intel TBB : Yes")
|
||||
elseif(TBB_FOUND)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ Prerequisites:
|
|||
|
||||
- [Boost](http://www.boost.org/users/download/) >= 1.43 (Ubuntu: `sudo apt-get install libboost-all-dev`)
|
||||
- [CMake](http://www.cmake.org/cmake/resources/software.html) >= 2.6 (Ubuntu: `sudo apt-get install cmake`)
|
||||
- A modern compiler, i.e., at least gcc 4.7.3 on Linux.
|
||||
|
||||
Optional prerequisites - used automatically if findable by CMake:
|
||||
|
||||
|
|
@ -46,6 +47,6 @@ See the [`INSTALL`](INSTALL) file for more detailed installation instructions.
|
|||
|
||||
GTSAM is open source under the BSD license, see the [`LICENSE`](LICENSE) and [`LICENSE.BSD`](LICENSE.BSD) files.
|
||||
|
||||
Please see the [`examples/`](examples) directory and the [`USAGE`](USAGE.md) file for examples on how to use GTSAM.
|
||||
|
||||
Please see the [`examples/`](examples) directory and the [`USAGE`](USAGE.md) file for examples on how to use GTSAM.
|
||||
|
||||
GTSAM was developed in the lab of [Frank Dellaert](http://www.cc.gatech.edu/~dellaert) at the [Georgia Institute of Technology](http://www.gatech.edu), with the help of many contributors over the years, see [THANKS](THANKS).
|
||||
|
|
@ -53,11 +53,12 @@ if(NOT FIRST_PASS_DONE)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
# Clang on Mac uses a template depth that is less than standard and is too small
|
||||
# Clang uses a template depth that is less than standard and is too small
|
||||
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
|
||||
if(NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "5.0")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024")
|
||||
endif()
|
||||
# Apple Clang before 5.0 does not support -ftemplate-depth.
|
||||
if(NOT (APPLE AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "5.0"))
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Set up build type library postfixes
|
||||
|
|
@ -97,7 +98,8 @@ if( NOT cmake_build_type_tolower STREQUAL ""
|
|||
AND NOT cmake_build_type_tolower STREQUAL "release"
|
||||
AND NOT cmake_build_type_tolower STREQUAL "timing"
|
||||
AND NOT cmake_build_type_tolower STREQUAL "profiling"
|
||||
AND NOT cmake_build_type_tolower STREQUAL "relwithdebinfo")
|
||||
AND NOT cmake_build_type_tolower STREQUAL "relwithdebinfo"
|
||||
AND NOT cmake_build_type_tolower STREQUAL "minsizerel")
|
||||
message(FATAL_ERROR "Unknown build type \"${CMAKE_BUILD_TYPE}\". Allowed values are None, Debug, Release, Timing, Profiling, RelWithDebInfo (case-insensitive).")
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ function(install_wrapped_library_internal interfaceHeader)
|
|||
if(GTSAM_BUILD_TYPE_POSTFIXES)
|
||||
foreach(build_type ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER "${build_type}" build_type_upper)
|
||||
if("${build_type_upper}" STREQUAL "RELEASE")
|
||||
if(${build_type_upper} STREQUAL "RELEASE")
|
||||
set(build_type_tag "") # Don't create release mode tag on installed directory
|
||||
else()
|
||||
set(build_type_tag "${build_type}")
|
||||
|
|
@ -367,13 +367,18 @@ endfunction()
|
|||
# should be installed to all build type toolboxes
|
||||
function(install_matlab_scripts source_directory patterns)
|
||||
set(patterns_args "")
|
||||
set(exclude_patterns "")
|
||||
if(NOT GTSAM_WRAP_SERIALIZATION)
|
||||
set(exclude_patterns "testSerialization.m")
|
||||
endif()
|
||||
|
||||
foreach(pattern ${patterns})
|
||||
list(APPEND patterns_args PATTERN "${pattern}")
|
||||
endforeach()
|
||||
if(GTSAM_BUILD_TYPE_POSTFIXES)
|
||||
foreach(build_type ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER "${build_type}" build_type_upper)
|
||||
if("${build_type_upper}" STREQUAL "RELEASE")
|
||||
if(${build_type_upper} STREQUAL "RELEASE")
|
||||
set(build_type_tag "") # Don't create release mode tag on installed directory
|
||||
else()
|
||||
set(build_type_tag "${build_type}")
|
||||
|
|
@ -381,10 +386,10 @@ function(install_matlab_scripts source_directory patterns)
|
|||
# Split up filename to strip trailing '/' in GTSAM_TOOLBOX_INSTALL_PATH if there is one
|
||||
get_filename_component(location "${GTSAM_TOOLBOX_INSTALL_PATH}" PATH)
|
||||
get_filename_component(name "${GTSAM_TOOLBOX_INSTALL_PATH}" NAME)
|
||||
install(DIRECTORY "${source_directory}" DESTINATION "${location}/${name}${build_type_tag}" CONFIGURATIONS "${build_type}" FILES_MATCHING ${patterns_args} PATTERN ".svn" EXCLUDE)
|
||||
install(DIRECTORY "${source_directory}" DESTINATION "${location}/${name}${build_type_tag}" CONFIGURATIONS "${build_type}" FILES_MATCHING ${patterns_args} PATTERN "${exclude_patterns}" EXCLUDE)
|
||||
endforeach()
|
||||
else()
|
||||
install(DIRECTORY "${source_directory}" DESTINATION "${GTSAM_TOOLBOX_INSTALL_PATH}" FILES_MATCHING ${patterns_args} PATTERN ".svn" EXCLUDE)
|
||||
install(DIRECTORY "${source_directory}" DESTINATION "${GTSAM_TOOLBOX_INSTALL_PATH}" FILES_MATCHING ${patterns_args} PATTERN "${exclude_patterns}" EXCLUDE)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
|
|
|||
|
|
@ -195,7 +195,9 @@ macro(gtsamAddTestsGlob_impl groupName globPatterns excludedFiles linkLibraries)
|
|||
add_test(NAME ${target_name} COMMAND ${target_name})
|
||||
add_dependencies(check.${groupName} ${target_name})
|
||||
add_dependencies(check ${target_name})
|
||||
add_dependencies(all.tests ${script_name})
|
||||
if(NOT XCODE_VERSION)
|
||||
add_dependencies(all.tests ${script_name})
|
||||
endif()
|
||||
|
||||
# Add TOPSRCDIR
|
||||
set_property(SOURCE ${script_srcs} APPEND PROPERTY COMPILE_DEFINITIONS "TOPSRCDIR=\"${PROJECT_SOURCE_DIR}\"")
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
/html/
|
||||
|
|
@ -0,0 +1 @@
|
|||
*.txt
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
// Also, we will initialize the robot at the origin using a Prior factor.
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
#include <gtsam/slam/BetweenFactor.h>
|
||||
#include <gtsam/slam/BearingRangeFactor.h>
|
||||
#include <gtsam/sam/BearingRangeFactor.h>
|
||||
|
||||
// When the factors are created, we will add them to a Factor Graph. As the factors we are using
|
||||
// are nonlinear factors, we will need a Nonlinear Factor Graph.
|
||||
|
|
|
|||
|
|
@ -14,20 +14,18 @@
|
|||
* @brief Expressions version of Pose2SLAMExample.cpp
|
||||
* @date Oct 2, 2014
|
||||
* @author Frank Dellaert
|
||||
* @author Yong Dian Jian
|
||||
*/
|
||||
|
||||
// The two new headers that allow using our Automatic Differentiation Expression framework
|
||||
#include <gtsam/slam/expressions.h>
|
||||
#include <gtsam/nonlinear/ExpressionFactorGraph.h>
|
||||
|
||||
// Header order is close to far
|
||||
#include <gtsam/nonlinear/NonlinearFactorGraph.h>
|
||||
// For an explanation of headers below, please see Pose2SLAMExample.cpp
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
#include <gtsam/slam/BetweenFactor.h>
|
||||
#include <gtsam/geometry/Pose2.h>
|
||||
#include <gtsam/nonlinear/GaussNewtonOptimizer.h>
|
||||
#include <gtsam/nonlinear/Marginals.h>
|
||||
#include <gtsam/nonlinear/Values.h>
|
||||
#include <gtsam/geometry/Pose2.h>
|
||||
#include <gtsam/inference/Key.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace gtsam;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <gtsam/slam/dataset.h>
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
#include <gtsam/geometry/Pose2.h>
|
||||
#include <gtsam/nonlinear/GaussNewtonOptimizer.h>
|
||||
#include <fstream>
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,15 @@
|
|||
* @author Frank Dellaert
|
||||
*/
|
||||
|
||||
#include <gtsam/slam/dataset.h>
|
||||
// For an explanation of headers below, please see Pose2SLAMExample.cpp
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
#include <gtsam/nonlinear/Marginals.h>
|
||||
#include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
|
||||
#include <gtsam/slam/BetweenFactor.h>
|
||||
#include <gtsam/geometry/Pose2.h>
|
||||
#include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
|
||||
#include <gtsam/nonlinear/Marginals.h>
|
||||
|
||||
// This new header allows us to read examples easily from .graph files
|
||||
#include <gtsam/slam/dataset.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace gtsam;
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@
|
|||
* @author Frank Dellaert
|
||||
*/
|
||||
|
||||
// For an explanation of headers below, please see Pose2SLAMExample.cpp
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
#include <gtsam/slam/BetweenFactor.h>
|
||||
#include <gtsam/nonlinear/Marginals.h>
|
||||
#include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
|
||||
#include <gtsam/geometry/Pose2.h>
|
||||
#include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <gtsam/slam/lago.h>
|
||||
#include <gtsam/slam/dataset.h>
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
#include <gtsam/geometry/Pose2.h>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
|
|
|||
|
|
@ -16,47 +16,15 @@
|
|||
* @date June 2, 2012
|
||||
*/
|
||||
|
||||
/**
|
||||
* A simple 2D pose slam example solved using a Conjugate-Gradient method
|
||||
* - The robot moves in a 2 meter square
|
||||
* - The robot moves 2 meters each step, turning 90 degrees after each step
|
||||
* - The robot initially faces along the X axis (horizontal, to the right in 2D)
|
||||
* - We have full odometry between pose
|
||||
* - We have a loop closure constraint when the robot returns to the first position
|
||||
*/
|
||||
|
||||
// As this is a planar SLAM example, we will use Pose2 variables (x, y, theta) to represent
|
||||
// the robot positions
|
||||
#include <gtsam/geometry/Pose2.h>
|
||||
#include <gtsam/geometry/Point2.h>
|
||||
|
||||
// Each variable in the system (poses) must be identified with a unique key.
|
||||
// We can either use simple integer keys (1, 2, 3, ...) or symbols (X1, X2, L1).
|
||||
// Here we will use simple integer keys
|
||||
#include <gtsam/inference/Key.h>
|
||||
|
||||
// In GTSAM, measurement functions are represented as 'factors'. Several common factors
|
||||
// have been provided with the library for solving robotics/SLAM/Bundle Adjustment problems.
|
||||
// Here we will use Between factors for the relative motion described by odometry measurements.
|
||||
// We will also use a Between Factor to encode the loop closure constraint
|
||||
// Also, we will initialize the robot at the origin using a Prior factor.
|
||||
// For an explanation of headers below, please see Pose2SLAMExample.cpp
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
#include <gtsam/slam/BetweenFactor.h>
|
||||
|
||||
// When the factors are created, we will add them to a Factor Graph. As the factors we are using
|
||||
// are nonlinear factors, we will need a Nonlinear Factor Graph.
|
||||
#include <gtsam/nonlinear/NonlinearFactorGraph.h>
|
||||
|
||||
// The nonlinear solvers within GTSAM are iterative solvers, meaning they linearize the
|
||||
// nonlinear functions around an initial linearization point, then solve the linear system
|
||||
// to update the linearization point. This happens repeatedly until the solver converges
|
||||
// to a consistent set of variable values. This requires us to specify an initial guess
|
||||
// for each variable, held in a Values container.
|
||||
#include <gtsam/nonlinear/Values.h>
|
||||
|
||||
#include <gtsam/linear/SubgraphSolver.h>
|
||||
#include <gtsam/geometry/Pose2.h>
|
||||
#include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
|
||||
|
||||
// In contrast to that example, however, we will use a PCG solver here
|
||||
#include <gtsam/linear/SubgraphSolver.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace gtsam;
|
||||
|
||||
|
|
@ -66,32 +34,24 @@ int main(int argc, char** argv) {
|
|||
NonlinearFactorGraph graph;
|
||||
|
||||
// 2a. Add a prior on the first pose, setting it to the origin
|
||||
// A prior factor consists of a mean and a noise model (covariance matrix)
|
||||
Pose2 prior(0.0, 0.0, 0.0); // prior at origin
|
||||
noiseModel::Diagonal::shared_ptr priorNoise = noiseModel::Diagonal::Sigmas(Vector3(0.3, 0.3, 0.1));
|
||||
graph.push_back(PriorFactor<Pose2>(1, prior, priorNoise));
|
||||
|
||||
// 2b. Add odometry factors
|
||||
// For simplicity, we will use the same noise model for each odometry factor
|
||||
noiseModel::Diagonal::shared_ptr odometryNoise = noiseModel::Diagonal::Sigmas(Vector3(0.2, 0.2, 0.1));
|
||||
// Create odometry (Between) factors between consecutive poses
|
||||
graph.push_back(BetweenFactor<Pose2>(1, 2, Pose2(2.0, 0.0, M_PI_2), odometryNoise));
|
||||
graph.push_back(BetweenFactor<Pose2>(2, 3, Pose2(2.0, 0.0, M_PI_2), odometryNoise));
|
||||
graph.push_back(BetweenFactor<Pose2>(3, 4, Pose2(2.0, 0.0, M_PI_2), odometryNoise));
|
||||
graph.push_back(BetweenFactor<Pose2>(4, 5, Pose2(2.0, 0.0, M_PI_2), odometryNoise));
|
||||
|
||||
// 2c. Add the loop closure constraint
|
||||
// This factor encodes the fact that we have returned to the same pose. In real systems,
|
||||
// these constraints may be identified in many ways, such as appearance-based techniques
|
||||
// with camera images.
|
||||
// We will use another Between Factor to enforce this constraint, with the distance set to zero,
|
||||
noiseModel::Diagonal::shared_ptr model = noiseModel::Diagonal::Sigmas(Vector3(0.2, 0.2, 0.1));
|
||||
graph.push_back(BetweenFactor<Pose2>(5, 1, Pose2(0.0, 0.0, 0.0), model));
|
||||
graph.print("\nFactor Graph:\n"); // print
|
||||
|
||||
|
||||
// 3. Create the data structure to hold the initialEstimate estimate to the solution
|
||||
// For illustrative purposes, these have been deliberately set to incorrect values
|
||||
Values initialEstimate;
|
||||
initialEstimate.insert(1, Pose2(0.5, 0.0, 0.2));
|
||||
initialEstimate.insert(2, Pose2(2.3, 0.1, 1.1));
|
||||
|
|
@ -104,15 +64,18 @@ int main(int argc, char** argv) {
|
|||
LevenbergMarquardtParams parameters;
|
||||
parameters.verbosity = NonlinearOptimizerParams::ERROR;
|
||||
parameters.verbosityLM = LevenbergMarquardtParams::LAMBDA;
|
||||
parameters.linearSolverType = NonlinearOptimizerParams::Iterative;
|
||||
|
||||
{
|
||||
parameters.iterativeParams = boost::make_shared<SubgraphSolverParameters>();
|
||||
LevenbergMarquardtOptimizer optimizer(graph, initialEstimate, parameters);
|
||||
Values result = optimizer.optimize();
|
||||
result.print("Final Result:\n");
|
||||
cout << "subgraph solver final error = " << graph.error(result) << endl;
|
||||
}
|
||||
// LM is still the outer optimization loop, but by specifying "Iterative" below
|
||||
// We indicate that an iterative linear solver should be used.
|
||||
// In addition, the *type* of the iterativeParams decides on the type of
|
||||
// iterative solver, in this case the SPCG (subgraph PCG)
|
||||
parameters.linearSolverType = NonlinearOptimizerParams::Iterative;
|
||||
parameters.iterativeParams = boost::make_shared<SubgraphSolverParameters>();
|
||||
|
||||
LevenbergMarquardtOptimizer optimizer(graph, initialEstimate, parameters);
|
||||
Values result = optimizer.optimize();
|
||||
result.print("Final Result:\n");
|
||||
cout << "subgraph solver final error = " << graph.error(result) << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
// have been provided with the library for solving robotics SLAM problems.
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
#include <gtsam/slam/BetweenFactor.h>
|
||||
#include <gtsam/slam/RangeFactor.h>
|
||||
#include <gtsam/sam/RangeFactor.h>
|
||||
#include <gtsam/slam/dataset.h>
|
||||
|
||||
// Standard headers, added last, so we know headers above work on their own
|
||||
|
|
|
|||
|
|
@ -15,13 +15,7 @@
|
|||
* @author Duy-Nguyen Ta
|
||||
*/
|
||||
|
||||
/**
|
||||
* A structure-from-motion example with landmarks
|
||||
* - The landmarks form a 10 meter cube
|
||||
* - The robot rotates around the landmarks, always facing towards the cube
|
||||
*/
|
||||
|
||||
// For loading the data
|
||||
// For loading the data, see the comments therein for scenario (camera rotates around cube)
|
||||
#include "SFMdata.h"
|
||||
|
||||
// Camera observations of landmarks (i.e. pixel coordinates) will be stored as Point2 (x, y).
|
||||
|
|
@ -103,7 +97,7 @@ int main(int argc, char* argv[]) {
|
|||
// Intentionally initialize the variables off from the ground truth
|
||||
Values initialEstimate;
|
||||
for (size_t i = 0; i < poses.size(); ++i)
|
||||
initialEstimate.insert(Symbol('x', i), poses[i].compose(Pose3(Rot3::rodriguez(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20))));
|
||||
initialEstimate.insert(Symbol('x', i), poses[i].compose(Pose3(Rot3::Rodrigues(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20))));
|
||||
for (size_t j = 0; j < points.size(); ++j)
|
||||
initialEstimate.insert(Symbol('l', j), points[j].compose(Point3(-0.25, 0.20, 0.15)));
|
||||
initialEstimate.print("Initial Estimates:\n");
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
// Create perturbed initial
|
||||
Values initial;
|
||||
Pose3 delta(Rot3::rodriguez(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20));
|
||||
Pose3 delta(Rot3::Rodrigues(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20));
|
||||
for (size_t i = 0; i < poses.size(); ++i)
|
||||
initial.insert(Symbol('x', i), poses[i].compose(delta));
|
||||
for (size_t j = 0; j < points.size(); ++j)
|
||||
|
|
|
|||
|
|
@ -17,51 +17,25 @@
|
|||
* @author Frank Dellaert
|
||||
*/
|
||||
|
||||
/**
|
||||
* A structure-from-motion example with landmarks
|
||||
* - The landmarks form a 10 meter cube
|
||||
* - The robot rotates around the landmarks, always facing towards the cube
|
||||
*/
|
||||
|
||||
// For loading the data
|
||||
#include "SFMdata.h"
|
||||
|
||||
// Camera observations of landmarks (i.e. pixel coordinates) will be stored as Point2 (x, y).
|
||||
#include <gtsam/geometry/Point2.h>
|
||||
|
||||
// In GTSAM, measurement functions are represented as 'factors'.
|
||||
// The factor we used here is SmartProjectionPoseFactor. Every smart factor represent a single landmark,
|
||||
// The SmartProjectionPoseFactor only optimize the pose of camera, not the calibration,
|
||||
// The calibration should be known.
|
||||
// The factor we used here is SmartProjectionPoseFactor.
|
||||
// Every smart factor represent a single landmark, seen from multiple cameras.
|
||||
// The SmartProjectionPoseFactor only optimizes for the poses of a camera,
|
||||
// not the calibration, which is assumed known.
|
||||
#include <gtsam/slam/SmartProjectionPoseFactor.h>
|
||||
|
||||
// Also, we will initialize the robot at some location using a Prior factor.
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
|
||||
// When the factors are created, we will add them to a Factor Graph. As the factors we are using
|
||||
// are nonlinear factors, we will need a Nonlinear Factor Graph.
|
||||
#include <gtsam/nonlinear/NonlinearFactorGraph.h>
|
||||
|
||||
// Finally, once all of the factors have been added to our factor graph, we will want to
|
||||
// solve/optimize to graph to find the best (Maximum A Posteriori) set of variable values.
|
||||
// GTSAM includes several nonlinear optimizers to perform this step. Here we will use a
|
||||
// trust-region method known as Powell's Degleg
|
||||
#include <gtsam/nonlinear/DoglegOptimizer.h>
|
||||
|
||||
// The nonlinear solvers within GTSAM are iterative solvers, meaning they linearize the
|
||||
// nonlinear functions around an initial linearization point, then solve the linear system
|
||||
// to update the linearization point. This happens repeatedly until the solver converges
|
||||
// to a consistent set of variable values. This requires us to specify an initial guess
|
||||
// for each variable, held in a Values container.
|
||||
#include <gtsam/nonlinear/Values.h>
|
||||
|
||||
#include <vector>
|
||||
// For an explanation of these headers, see SFMExample.cpp
|
||||
#include "SFMdata.h"
|
||||
#include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace gtsam;
|
||||
|
||||
// Make the typename short so it looks much cleaner
|
||||
typedef gtsam::SmartProjectionPoseFactor<gtsam::Pose3, gtsam::Cal3_S2> SmartFactor;
|
||||
typedef SmartProjectionPoseFactor<Cal3_S2> SmartFactor;
|
||||
|
||||
// create a typedef to the camera type
|
||||
typedef PinholePose<Cal3_S2> Camera;
|
||||
|
||||
/* ************************************************************************* */
|
||||
int main(int argc, char* argv[]) {
|
||||
|
|
@ -84,12 +58,12 @@ int main(int argc, char* argv[]) {
|
|||
for (size_t j = 0; j < points.size(); ++j) {
|
||||
|
||||
// every landmark represent a single landmark, we use shared pointer to init the factor, and then insert measurements.
|
||||
SmartFactor::shared_ptr smartfactor(new SmartFactor());
|
||||
SmartFactor::shared_ptr smartfactor(new SmartFactor(measurementNoise, K));
|
||||
|
||||
for (size_t i = 0; i < poses.size(); ++i) {
|
||||
|
||||
// generate the 2D measurement
|
||||
SimpleCamera camera(poses[i], *K);
|
||||
Camera camera(poses[i], K);
|
||||
Point2 measurement = camera.project(points[j]);
|
||||
|
||||
// call add() function to add measurement into a single factor, here we need to add:
|
||||
|
|
@ -97,7 +71,7 @@ int main(int argc, char* argv[]) {
|
|||
// 2. the corresponding camera's key
|
||||
// 3. camera noise model
|
||||
// 4. camera calibration
|
||||
smartfactor->add(measurement, i, measurementNoise, K);
|
||||
smartfactor->add(measurement, i);
|
||||
}
|
||||
|
||||
// insert the smart factor in the graph
|
||||
|
|
@ -106,28 +80,29 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
// Add a prior on pose x0. This indirectly specifies where the origin is.
|
||||
// 30cm std on x,y,z 0.1 rad on roll,pitch,yaw
|
||||
noiseModel::Diagonal::shared_ptr poseNoise = noiseModel::Diagonal::Sigmas(
|
||||
noiseModel::Diagonal::shared_ptr noise = noiseModel::Diagonal::Sigmas(
|
||||
(Vector(6) << Vector3::Constant(0.3), Vector3::Constant(0.1)).finished());
|
||||
graph.push_back(PriorFactor<Pose3>(0, poses[0], poseNoise));
|
||||
graph.push_back(PriorFactor<Camera>(0, Camera(poses[0],K), noise));
|
||||
|
||||
// Because the structure-from-motion problem has a scale ambiguity, the problem is
|
||||
// still under-constrained. Here we add a prior on the second pose x1, so this will
|
||||
// fix the scale by indicating the distance between x0 and x1.
|
||||
// Because these two are fixed, the rest of the poses will be also be fixed.
|
||||
graph.push_back(PriorFactor<Pose3>(1, poses[1], poseNoise)); // add directly to graph
|
||||
graph.push_back(PriorFactor<Camera>(1, Camera(poses[1],K), noise)); // add directly to graph
|
||||
|
||||
graph.print("Factor Graph:\n");
|
||||
|
||||
// Create the initial estimate to the solution
|
||||
// Intentionally initialize the variables off from the ground truth
|
||||
Values initialEstimate;
|
||||
Pose3 delta(Rot3::rodriguez(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20));
|
||||
Pose3 delta(Rot3::Rodrigues(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20));
|
||||
for (size_t i = 0; i < poses.size(); ++i)
|
||||
initialEstimate.insert(i, poses[i].compose(delta));
|
||||
initialEstimate.insert(i, Camera(poses[i].compose(delta), K));
|
||||
initialEstimate.print("Initial Estimates:\n");
|
||||
|
||||
// Optimize the graph and print results
|
||||
Values result = DoglegOptimizer(graph, initialEstimate).optimize();
|
||||
LevenbergMarquardtOptimizer optimizer(graph, initialEstimate);
|
||||
Values result = optimizer.optimize();
|
||||
result.print("Final results:\n");
|
||||
|
||||
// A smart factor represent the 3D point inside the factor, not as a variable.
|
||||
|
|
@ -136,20 +111,20 @@ int main(int argc, char* argv[]) {
|
|||
Values landmark_result;
|
||||
for (size_t j = 0; j < points.size(); ++j) {
|
||||
|
||||
// The output of point() is in boost::optional<gtsam::Point3>, as sometimes
|
||||
// the triangulation operation inside smart factor will encounter degeneracy.
|
||||
boost::optional<Point3> point;
|
||||
|
||||
// The graph stores Factor shared_ptrs, so we cast back to a SmartFactor first
|
||||
SmartFactor::shared_ptr smart = boost::dynamic_pointer_cast<SmartFactor>(graph[j]);
|
||||
if (smart) {
|
||||
point = smart->point(result);
|
||||
// The output of point() is in boost::optional<Point3>, as sometimes
|
||||
// the triangulation operation inside smart factor will encounter degeneracy.
|
||||
boost::optional<Point3> point = smart->point(result);
|
||||
if (point) // ignore if boost::optional return NULL
|
||||
landmark_result.insert(j, *point);
|
||||
}
|
||||
}
|
||||
|
||||
landmark_result.print("Landmark results:\n");
|
||||
cout << "final error: " << graph.error(result) << endl;
|
||||
cout << "number of iterations: " << optimizer.iterations() << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file SFMExample_SmartFactorPCG.cpp
|
||||
* @brief Version of SFMExample_SmartFactor that uses Preconditioned Conjugate Gradient
|
||||
* @author Frank Dellaert
|
||||
*/
|
||||
|
||||
// For an explanation of these headers, see SFMExample_SmartFactor.cpp
|
||||
#include "SFMdata.h"
|
||||
#include <gtsam/slam/SmartProjectionPoseFactor.h>
|
||||
|
||||
// These extra headers allow us a LM outer loop with PCG linear solver (inner loop)
|
||||
#include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
|
||||
#include <gtsam/linear/Preconditioner.h>
|
||||
#include <gtsam/linear/PCGSolver.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace gtsam;
|
||||
|
||||
// Make the typename short so it looks much cleaner
|
||||
typedef SmartProjectionPoseFactor<Cal3_S2> SmartFactor;
|
||||
|
||||
// create a typedef to the camera type
|
||||
typedef PinholePose<Cal3_S2> Camera;
|
||||
|
||||
/* ************************************************************************* */
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
// Define the camera calibration parameters
|
||||
Cal3_S2::shared_ptr K(new Cal3_S2(50.0, 50.0, 0.0, 50.0, 50.0));
|
||||
|
||||
// Define the camera observation noise model
|
||||
noiseModel::Isotropic::shared_ptr measurementNoise =
|
||||
noiseModel::Isotropic::Sigma(2, 1.0); // one pixel in u and v
|
||||
|
||||
// Create the set of ground-truth landmarks and poses
|
||||
vector<Point3> points = createPoints();
|
||||
vector<Pose3> poses = createPoses();
|
||||
|
||||
// Create a factor graph
|
||||
NonlinearFactorGraph graph;
|
||||
|
||||
// Simulated measurements from each camera pose, adding them to the factor graph
|
||||
for (size_t j = 0; j < points.size(); ++j) {
|
||||
|
||||
// every landmark represent a single landmark, we use shared pointer to init the factor, and then insert measurements.
|
||||
SmartFactor::shared_ptr smartfactor(new SmartFactor(measurementNoise, K));
|
||||
|
||||
for (size_t i = 0; i < poses.size(); ++i) {
|
||||
|
||||
// generate the 2D measurement
|
||||
Camera camera(poses[i], K);
|
||||
Point2 measurement = camera.project(points[j]);
|
||||
|
||||
// call add() function to add measurement into a single factor, here we need to add:
|
||||
smartfactor->add(measurement, i);
|
||||
}
|
||||
|
||||
// insert the smart factor in the graph
|
||||
graph.push_back(smartfactor);
|
||||
}
|
||||
|
||||
// Add a prior on pose x0. This indirectly specifies where the origin is.
|
||||
// 30cm std on x,y,z 0.1 rad on roll,pitch,yaw
|
||||
noiseModel::Diagonal::shared_ptr noise = noiseModel::Diagonal::Sigmas(
|
||||
(Vector(6) << Vector3::Constant(0.3), Vector3::Constant(0.1)).finished());
|
||||
graph.push_back(PriorFactor<Camera>(0, Camera(poses[0],K), noise));
|
||||
|
||||
// Fix the scale ambiguity by adding a prior
|
||||
graph.push_back(PriorFactor<Camera>(1, Camera(poses[0],K), noise));
|
||||
|
||||
// Create the initial estimate to the solution
|
||||
Values initialEstimate;
|
||||
Pose3 delta(Rot3::Rodrigues(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20));
|
||||
for (size_t i = 0; i < poses.size(); ++i)
|
||||
initialEstimate.insert(i, Camera(poses[i].compose(delta),K));
|
||||
|
||||
// We will use LM in the outer optimization loop, but by specifying "Iterative" below
|
||||
// We indicate that an iterative linear solver should be used.
|
||||
// In addition, the *type* of the iterativeParams decides on the type of
|
||||
// iterative solver, in this case the SPCG (subgraph PCG)
|
||||
LevenbergMarquardtParams parameters;
|
||||
parameters.linearSolverType = NonlinearOptimizerParams::Iterative;
|
||||
parameters.absoluteErrorTol = 1e-10;
|
||||
parameters.relativeErrorTol = 1e-10;
|
||||
parameters.maxIterations = 500;
|
||||
PCGSolverParameters::shared_ptr pcg =
|
||||
boost::make_shared<PCGSolverParameters>();
|
||||
pcg->preconditioner_ =
|
||||
boost::make_shared<BlockJacobiPreconditionerParameters>();
|
||||
// Following is crucial:
|
||||
pcg->setEpsilon_abs(1e-10);
|
||||
pcg->setEpsilon_rel(1e-10);
|
||||
parameters.iterativeParams = pcg;
|
||||
|
||||
LevenbergMarquardtOptimizer optimizer(graph, initialEstimate, parameters);
|
||||
Values result = optimizer.optimize();
|
||||
|
||||
// Display result as in SFMExample_SmartFactor.run
|
||||
result.print("Final results:\n");
|
||||
Values landmark_result;
|
||||
for (size_t j = 0; j < points.size(); ++j) {
|
||||
SmartFactor::shared_ptr smart = //
|
||||
boost::dynamic_pointer_cast<SmartFactor>(graph[j]);
|
||||
if (smart) {
|
||||
boost::optional<Point3> point = smart->point(result);
|
||||
if (point) // ignore if boost::optional return NULL
|
||||
landmark_result.insert(j, *point);
|
||||
}
|
||||
}
|
||||
|
||||
landmark_result.print("Landmark results:\n");
|
||||
cout << "final error: " << graph.error(result) << endl;
|
||||
cout << "number of iterations: " << optimizer.iterations() << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* ************************************************************************* */
|
||||
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
||||
* Atlanta, Georgia 30332-0415
|
||||
* All Rights Reserved
|
||||
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
||||
|
||||
* See LICENSE for the license information
|
||||
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file SFMExample.cpp
|
||||
* @brief This file is to compare the ordering performance for COLAMD vs METIS.
|
||||
* Example problem is to solve a structure-from-motion problem from a "Bundle Adjustment in the Large" file.
|
||||
* @author Frank Dellaert, Zhaoyang Lv
|
||||
*/
|
||||
|
||||
// For an explanation of headers, see SFMExample.cpp
|
||||
#include <gtsam/inference/Symbol.h>
|
||||
#include <gtsam/inference/Ordering.h>
|
||||
#include <gtsam/nonlinear/NonlinearFactorGraph.h>
|
||||
#include <gtsam/nonlinear/LevenbergMarquardtOptimizer.h>
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
#include <gtsam/slam/GeneralSFMFactor.h>
|
||||
#include <gtsam/slam/dataset.h> // for loading BAL datasets !
|
||||
|
||||
#include <gtsam/base/timing.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
using namespace gtsam;
|
||||
using symbol_shorthand::C;
|
||||
using symbol_shorthand::P;
|
||||
|
||||
// We will be using a projection factor that ties a SFM_Camera to a 3D point.
|
||||
// An SFM_Camera is defined in datase.h as a camera with unknown Cal3Bundler calibration
|
||||
// and has a total of 9 free parameters
|
||||
typedef GeneralSFMFactor<SfM_Camera,Point3> MyFactor;
|
||||
|
||||
/* ************************************************************************* */
|
||||
int main (int argc, char* argv[]) {
|
||||
|
||||
// Find default file, but if an argument is given, try loading a file
|
||||
string filename = findExampleDataFile("dubrovnik-3-7-pre");
|
||||
if (argc>1) filename = string(argv[1]);
|
||||
|
||||
// Load the SfM data from file
|
||||
SfM_data mydata;
|
||||
readBAL(filename, mydata);
|
||||
cout << boost::format("read %1% tracks on %2% cameras\n") % mydata.number_tracks() % mydata.number_cameras();
|
||||
|
||||
// Create a factor graph
|
||||
NonlinearFactorGraph graph;
|
||||
|
||||
// We share *one* noiseModel between all projection factors
|
||||
noiseModel::Isotropic::shared_ptr noise =
|
||||
noiseModel::Isotropic::Sigma(2, 1.0); // one pixel in u and v
|
||||
|
||||
// Add measurements to the factor graph
|
||||
size_t j = 0;
|
||||
BOOST_FOREACH(const SfM_Track& track, mydata.tracks) {
|
||||
BOOST_FOREACH(const SfM_Measurement& m, track.measurements) {
|
||||
size_t i = m.first;
|
||||
Point2 uv = m.second;
|
||||
graph.push_back(MyFactor(uv, noise, C(i), P(j))); // note use of shorthand symbols C and P
|
||||
}
|
||||
j += 1;
|
||||
}
|
||||
|
||||
// Add a prior on pose x1. This indirectly specifies where the origin is.
|
||||
// and a prior on the position of the first landmark to fix the scale
|
||||
graph.push_back(PriorFactor<SfM_Camera>(C(0), mydata.cameras[0], noiseModel::Isotropic::Sigma(9, 0.1)));
|
||||
graph.push_back(PriorFactor<Point3> (P(0), mydata.tracks[0].p, noiseModel::Isotropic::Sigma(3, 0.1)));
|
||||
|
||||
// Create initial estimate
|
||||
Values initial;
|
||||
size_t i = 0; j = 0;
|
||||
BOOST_FOREACH(const SfM_Camera& camera, mydata.cameras) initial.insert(C(i++), camera);
|
||||
BOOST_FOREACH(const SfM_Track& track, mydata.tracks) initial.insert(P(j++), track.p);
|
||||
|
||||
/** --------------- COMPARISON -----------------------**/
|
||||
/** ----------------------------------------------------**/
|
||||
|
||||
LevenbergMarquardtParams params_using_COLAMD, params_using_METIS;
|
||||
try {
|
||||
params_using_METIS.setVerbosity("ERROR");
|
||||
gttic_(METIS_ORDERING);
|
||||
params_using_METIS.ordering = Ordering::Create(Ordering::METIS, graph);
|
||||
gttoc_(METIS_ORDERING);
|
||||
|
||||
params_using_COLAMD.setVerbosity("ERROR");
|
||||
gttic_(COLAMD_ORDERING);
|
||||
params_using_COLAMD.ordering = Ordering::Create(Ordering::COLAMD, graph);
|
||||
gttoc_(COLAMD_ORDERING);
|
||||
} catch (exception& e) {
|
||||
cout << e.what();
|
||||
}
|
||||
|
||||
// expect they have different ordering results
|
||||
if(params_using_COLAMD.ordering == params_using_METIS.ordering) {
|
||||
cout << "COLAMD and METIS produce the same ordering. "
|
||||
<< "Problem here!!!" << endl;
|
||||
}
|
||||
|
||||
/* Optimize the graph with METIS and COLAMD and time the results */
|
||||
|
||||
Values result_METIS, result_COLAMD;
|
||||
try {
|
||||
gttic_(OPTIMIZE_WITH_METIS);
|
||||
LevenbergMarquardtOptimizer lm_METIS(graph, initial, params_using_METIS);
|
||||
result_METIS = lm_METIS.optimize();
|
||||
gttoc_(OPTIMIZE_WITH_METIS);
|
||||
|
||||
gttic_(OPTIMIZE_WITH_COLAMD);
|
||||
LevenbergMarquardtOptimizer lm_COLAMD(graph, initial, params_using_COLAMD);
|
||||
result_COLAMD = lm_COLAMD.optimize();
|
||||
gttoc_(OPTIMIZE_WITH_COLAMD);
|
||||
} catch (exception& e) {
|
||||
cout << e.what();
|
||||
}
|
||||
|
||||
|
||||
{ // printing the result
|
||||
|
||||
cout << "COLAMD final error: " << graph.error(result_COLAMD) << endl;
|
||||
cout << "METIS final error: " << graph.error(result_METIS) << endl;
|
||||
|
||||
cout << endl << endl;
|
||||
|
||||
cout << "Time comparison by solving " << filename << " results:" << endl;
|
||||
cout << boost::format("%1% point tracks and %2% cameras\n") \
|
||||
% mydata.number_tracks() % mydata.number_cameras() \
|
||||
<< endl;
|
||||
|
||||
tictoc_print_();
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* ************************************************************************* */
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ int main(int argc, char* argv[]) {
|
|||
Values initialEstimate;
|
||||
initialEstimate.insert(Symbol('K', 0), Cal3_S2(60.0, 60.0, 0.0, 45.0, 45.0));
|
||||
for (size_t i = 0; i < poses.size(); ++i)
|
||||
initialEstimate.insert(Symbol('x', i), poses[i].compose(Pose3(Rot3::rodriguez(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20))));
|
||||
initialEstimate.insert(Symbol('x', i), poses[i].compose(Pose3(Rot3::Rodrigues(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20))));
|
||||
for (size_t j = 0; j < points.size(); ++j)
|
||||
initialEstimate.insert(Symbol('l', j), points[j].compose(Point3(-0.25, 0.20, 0.15)));
|
||||
|
||||
|
|
|
|||
|
|
@ -31,28 +31,30 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <gtsam/base/timing.h>
|
||||
#include <gtsam/base/treeTraversal-inst.h>
|
||||
#include <gtsam/slam/dataset.h>
|
||||
#include <gtsam/geometry/Pose2.h>
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
#include <gtsam/slam/BetweenFactor.h>
|
||||
#include <gtsam/slam/BearingRangeFactor.h>
|
||||
#include <gtsam/inference/Symbol.h>
|
||||
#include <gtsam/linear/GaussianJunctionTree.h>
|
||||
#include <gtsam/linear/GaussianEliminationTree.h>
|
||||
#include <gtsam/sam/BearingRangeFactor.h>
|
||||
#include <gtsam/slam/dataset.h>
|
||||
#include <gtsam/slam/PriorFactor.h>
|
||||
#include <gtsam/geometry/Pose2.h>
|
||||
#include <gtsam/nonlinear/ISAM2.h>
|
||||
#include <gtsam/nonlinear/GaussNewtonOptimizer.h>
|
||||
#include <gtsam/nonlinear/Marginals.h>
|
||||
#include <gtsam/linear/GaussianJunctionTree.h>
|
||||
#include <gtsam/linear/GaussianEliminationTree.h>
|
||||
#include <gtsam/inference/Symbol.h>
|
||||
#include <gtsam/base/timing.h>
|
||||
#include <gtsam/base/treeTraversal-inst.h>
|
||||
#include <gtsam/config.h> // for GTSAM_USE_TBB
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <boost/archive/binary_oarchive.hpp>
|
||||
#include <boost/archive/binary_iarchive.hpp>
|
||||
#include <boost/serialization/export.hpp>
|
||||
#include <boost/archive/binary_oarchive.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/range/algorithm/set_algorithm.hpp>
|
||||
#include <boost/random.hpp>
|
||||
#include <boost/serialization/export.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef GTSAM_USE_TBB
|
||||
#include <tbb/tbb.h>
|
||||
|
|
@ -72,23 +74,6 @@ typedef NoiseModelFactor1<Pose> NM1;
|
|||
typedef NoiseModelFactor2<Pose,Pose> NM2;
|
||||
typedef BearingRangeFactor<Pose,Point2> BR;
|
||||
|
||||
//GTSAM_VALUE_EXPORT(Value);
|
||||
//GTSAM_VALUE_EXPORT(Pose);
|
||||
//GTSAM_VALUE_EXPORT(Rot2);
|
||||
//GTSAM_VALUE_EXPORT(Point2);
|
||||
//GTSAM_VALUE_EXPORT(NonlinearFactor);
|
||||
//GTSAM_VALUE_EXPORT(NoiseModelFactor);
|
||||
//GTSAM_VALUE_EXPORT(NM1);
|
||||
//GTSAM_VALUE_EXPORT(NM2);
|
||||
//GTSAM_VALUE_EXPORT(BetweenFactor<Pose>);
|
||||
//GTSAM_VALUE_EXPORT(PriorFactor<Pose>);
|
||||
//GTSAM_VALUE_EXPORT(BR);
|
||||
//GTSAM_VALUE_EXPORT(noiseModel::Base);
|
||||
//GTSAM_VALUE_EXPORT(noiseModel::Isotropic);
|
||||
//GTSAM_VALUE_EXPORT(noiseModel::Gaussian);
|
||||
//GTSAM_VALUE_EXPORT(noiseModel::Diagonal);
|
||||
//GTSAM_VALUE_EXPORT(noiseModel::Unit);
|
||||
|
||||
double chi2_red(const gtsam::NonlinearFactorGraph& graph, const gtsam::Values& config) {
|
||||
// Compute degrees of freedom (observations - variables)
|
||||
// In ocaml, +1 was added to the observations to account for the prior, but
|
||||
|
|
@ -269,12 +254,12 @@ void runIncremental()
|
|||
boost::dynamic_pointer_cast<BetweenFactor<Pose> >(datasetMeasurements[nextMeasurement]))
|
||||
{
|
||||
Key key1 = measurement->key1(), key2 = measurement->key2();
|
||||
if((key1 >= firstStep && key1 < key2) || (key2 >= firstStep && key2 < key1)) {
|
||||
if(((int)key1 >= firstStep && key1 < key2) || ((int)key2 >= firstStep && key2 < key1)) {
|
||||
// We found an odometry starting at firstStep
|
||||
firstPose = std::min(key1, key2);
|
||||
break;
|
||||
}
|
||||
if((key2 >= firstStep && key1 < key2) || (key1 >= firstStep && key2 < key1)) {
|
||||
if(((int)key2 >= firstStep && key1 < key2) || ((int)key1 >= firstStep && key2 < key1)) {
|
||||
// We found an odometry joining firstStep with a previous pose
|
||||
havePreviousPose = true;
|
||||
firstPose = std::max(key1, key2);
|
||||
|
|
@ -303,7 +288,9 @@ void runIncremental()
|
|||
|
||||
cout << "Playing forward time steps..." << endl;
|
||||
|
||||
for(size_t step = firstPose; nextMeasurement < datasetMeasurements.size() && (lastStep == -1 || step <= lastStep); ++step)
|
||||
for (size_t step = firstPose;
|
||||
nextMeasurement < datasetMeasurements.size() && (lastStep == -1 || (int)step <= lastStep);
|
||||
++step)
|
||||
{
|
||||
Values newVariables;
|
||||
NonlinearFactorGraph newFactors;
|
||||
|
|
@ -589,7 +576,7 @@ void runStats()
|
|||
{
|
||||
cout << "Gathering statistics..." << endl;
|
||||
GaussianFactorGraph linear = *datasetMeasurements.linearize(initial);
|
||||
GaussianJunctionTree jt(GaussianEliminationTree(linear, Ordering::colamd(linear)));
|
||||
GaussianJunctionTree jt(GaussianEliminationTree(linear, Ordering::Colamd(linear)));
|
||||
treeTraversal::ForestStatistics statistics = treeTraversal::GatherStatistics(jt);
|
||||
|
||||
ofstream file;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <gtsam/global_includes.h>
|
||||
#include <gtsam/base/Matrix.h>
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <map>
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
// Add an initial guess for the current pose
|
||||
// Intentionally initialize the variables off from the ground truth
|
||||
initialEstimate.insert(Symbol('x', i), poses[i].compose(Pose3(Rot3::rodriguez(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20))));
|
||||
initialEstimate.insert(Symbol('x', i), poses[i].compose(Pose3(Rot3::Rodrigues(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20))));
|
||||
|
||||
// If this is the first iteration, add a prior on the first pose to set the coordinate frame
|
||||
// and a prior on the first landmark to set the scale
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ int main(int argc, char* argv[]) {
|
|||
}
|
||||
|
||||
// Intentionally initialize the variables off from the ground truth
|
||||
Pose3 noise(Rot3::rodriguez(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20));
|
||||
Pose3 noise(Rot3::Rodrigues(-0.1, 0.2, 0.25), Point3(0.05, -0.10, 0.20));
|
||||
Pose3 initial_xi = poses[i].compose(noise);
|
||||
|
||||
// Add an initial guess for the current pose
|
||||
|
|
|
|||
301
gtsam.h
301
gtsam.h
|
|
@ -1,4 +1,5 @@
|
|||
/**
|
||||
|
||||
* GTSAM Wrap Module Definition
|
||||
*
|
||||
* These are the current classes available through the matlab toolbox interface,
|
||||
|
|
@ -156,7 +157,7 @@ virtual class Value {
|
|||
size_t dim() const;
|
||||
};
|
||||
|
||||
#include <gtsam/base/LieScalar.h>
|
||||
#include <gtsam/base/deprecated/LieScalar.h>
|
||||
class LieScalar {
|
||||
// Standard constructors
|
||||
LieScalar();
|
||||
|
|
@ -185,7 +186,7 @@ class LieScalar {
|
|||
static Vector Logmap(const gtsam::LieScalar& p);
|
||||
};
|
||||
|
||||
#include <gtsam/base/LieVector.h>
|
||||
#include <gtsam/base/deprecated/LieVector.h>
|
||||
class LieVector {
|
||||
// Standard constructors
|
||||
LieVector();
|
||||
|
|
@ -217,7 +218,7 @@ class LieVector {
|
|||
void serialize() const;
|
||||
};
|
||||
|
||||
#include <gtsam/base/LieMatrix.h>
|
||||
#include <gtsam/base/deprecated/LieMatrix.h>
|
||||
class LieMatrix {
|
||||
// Standard constructors
|
||||
LieMatrix();
|
||||
|
|
@ -288,6 +289,32 @@ class Point2 {
|
|||
void serialize() const;
|
||||
};
|
||||
|
||||
// std::vector<gtsam::Point2>
|
||||
class Point2Vector
|
||||
{
|
||||
// Constructors
|
||||
Point2Vector();
|
||||
Point2Vector(const gtsam::Point2Vector& v);
|
||||
|
||||
//Capacity
|
||||
size_t size() const;
|
||||
size_t max_size() const;
|
||||
void resize(size_t sz);
|
||||
size_t capacity() const;
|
||||
bool empty() const;
|
||||
void reserve(size_t n);
|
||||
|
||||
//Element access
|
||||
gtsam::Point2 at(size_t n) const;
|
||||
gtsam::Point2 front() const;
|
||||
gtsam::Point2 back() const;
|
||||
|
||||
//Modifiers
|
||||
void assign(size_t n, const gtsam::Point2& u);
|
||||
void push_back(const gtsam::Point2& x);
|
||||
void pop_back();
|
||||
};
|
||||
|
||||
class StereoPoint2 {
|
||||
// Standard Constructors
|
||||
StereoPoint2();
|
||||
|
|
@ -304,8 +331,6 @@ class StereoPoint2 {
|
|||
gtsam::StereoPoint2 between(const gtsam::StereoPoint2& p2) const;
|
||||
|
||||
// Manifold
|
||||
static size_t Dim();
|
||||
size_t dim() const;
|
||||
gtsam::StereoPoint2 retract(Vector v) const;
|
||||
Vector localCoordinates(const gtsam::StereoPoint2& p) const;
|
||||
|
||||
|
|
@ -414,7 +439,7 @@ class Rot3 {
|
|||
static gtsam::Rot3 roll(double t); // positive roll is to right (increasing yaw in aircraft)
|
||||
static gtsam::Rot3 ypr(double y, double p, double r);
|
||||
static gtsam::Rot3 quaternion(double w, double x, double y, double z);
|
||||
static gtsam::Rot3 rodriguez(Vector v);
|
||||
static gtsam::Rot3 Rodrigues(Vector v);
|
||||
|
||||
// Testable
|
||||
void print(string s) const;
|
||||
|
|
@ -550,6 +575,16 @@ class Pose3 {
|
|||
void serialize() const;
|
||||
};
|
||||
|
||||
// std::vector<gtsam::Pose3>
|
||||
class Pose3Vector
|
||||
{
|
||||
Pose3Vector();
|
||||
size_t size() const;
|
||||
bool empty() const;
|
||||
gtsam::Pose3 at(size_t n) const;
|
||||
void push_back(const gtsam::Pose3& x);
|
||||
};
|
||||
|
||||
#include <gtsam/geometry/Unit3.h>
|
||||
class Unit3 {
|
||||
// Standard Constructors
|
||||
|
|
@ -778,7 +813,7 @@ class CalibratedCamera {
|
|||
|
||||
// Action on Point3
|
||||
gtsam::Point2 project(const gtsam::Point3& point) const;
|
||||
static gtsam::Point2 project_to_camera(const gtsam::Point3& cameraPoint);
|
||||
static gtsam::Point2 Project(const gtsam::Point3& cameraPoint);
|
||||
|
||||
// Standard Interface
|
||||
gtsam::Pose3 pose() const;
|
||||
|
|
@ -788,56 +823,16 @@ class CalibratedCamera {
|
|||
void serialize() const;
|
||||
};
|
||||
|
||||
class SimpleCamera {
|
||||
// Standard Constructors and Named Constructors
|
||||
SimpleCamera();
|
||||
SimpleCamera(const gtsam::Pose3& pose);
|
||||
SimpleCamera(const gtsam::Pose3& pose, const gtsam::Cal3_S2& K);
|
||||
static gtsam::SimpleCamera Level(const gtsam::Cal3_S2& K,
|
||||
const gtsam::Pose2& pose, double height);
|
||||
static gtsam::SimpleCamera Level(const gtsam::Pose2& pose, double height);
|
||||
static gtsam::SimpleCamera Lookat(const gtsam::Point3& eye,
|
||||
const gtsam::Point3& target, const gtsam::Point3& upVector,
|
||||
const gtsam::Cal3_S2& K);
|
||||
|
||||
// Testable
|
||||
void print(string s) const;
|
||||
bool equals(const gtsam::SimpleCamera& camera, double tol) const;
|
||||
|
||||
// Standard Interface
|
||||
gtsam::Pose3 pose() const;
|
||||
gtsam::Cal3_S2 calibration();
|
||||
|
||||
// Manifold
|
||||
gtsam::SimpleCamera retract(const Vector& d) const;
|
||||
Vector localCoordinates(const gtsam::SimpleCamera& T2) const;
|
||||
size_t dim() const;
|
||||
static size_t Dim();
|
||||
|
||||
// Transformations and measurement functions
|
||||
static gtsam::Point2 project_to_camera(const gtsam::Point3& cameraPoint);
|
||||
pair<gtsam::Point2,bool> projectSafe(const gtsam::Point3& pw) const;
|
||||
gtsam::Point2 project(const gtsam::Point3& point);
|
||||
gtsam::Point3 backproject(const gtsam::Point2& p, double depth) const;
|
||||
double range(const gtsam::Point3& point);
|
||||
double range(const gtsam::Pose3& point);
|
||||
|
||||
// enabling serialization functionality
|
||||
void serialize() const;
|
||||
};
|
||||
|
||||
template<CALIBRATION = {gtsam::Cal3DS2}>
|
||||
template<CALIBRATION>
|
||||
class PinholeCamera {
|
||||
// Standard Constructors and Named Constructors
|
||||
PinholeCamera();
|
||||
PinholeCamera(const gtsam::Pose3& pose);
|
||||
PinholeCamera(const gtsam::Pose3& pose, const gtsam::Cal3DS2& K);
|
||||
static This Level(const gtsam::Cal3DS2& K,
|
||||
const gtsam::Pose2& pose, double height);
|
||||
PinholeCamera(const gtsam::Pose3& pose, const CALIBRATION& K);
|
||||
static This Level(const CALIBRATION& K, const gtsam::Pose2& pose, double height);
|
||||
static This Level(const gtsam::Pose2& pose, double height);
|
||||
static This Lookat(const gtsam::Point3& eye,
|
||||
const gtsam::Point3& target, const gtsam::Point3& upVector,
|
||||
const gtsam::Cal3DS2& K);
|
||||
static This Lookat(const gtsam::Point3& eye, const gtsam::Point3& target,
|
||||
const gtsam::Point3& upVector, const CALIBRATION& K);
|
||||
|
||||
// Testable
|
||||
void print(string s) const;
|
||||
|
|
@ -854,7 +849,7 @@ class PinholeCamera {
|
|||
static size_t Dim();
|
||||
|
||||
// Transformations and measurement functions
|
||||
static gtsam::Point2 project_to_camera(const gtsam::Point3& cameraPoint);
|
||||
static gtsam::Point2 Project(const gtsam::Point3& cameraPoint);
|
||||
pair<gtsam::Point2,bool> projectSafe(const gtsam::Point3& pw) const;
|
||||
gtsam::Point2 project(const gtsam::Point3& point);
|
||||
gtsam::Point3 backproject(const gtsam::Point2& p, double depth) const;
|
||||
|
|
@ -865,6 +860,50 @@ class PinholeCamera {
|
|||
void serialize() const;
|
||||
};
|
||||
|
||||
virtual class SimpleCamera {
|
||||
// Standard Constructors and Named Constructors
|
||||
SimpleCamera();
|
||||
SimpleCamera(const gtsam::Pose3& pose);
|
||||
SimpleCamera(const gtsam::Pose3& pose, const gtsam::Cal3_S2& K);
|
||||
static gtsam::SimpleCamera Level(const gtsam::Cal3_S2& K, const gtsam::Pose2& pose, double height);
|
||||
static gtsam::SimpleCamera Level(const gtsam::Pose2& pose, double height);
|
||||
static gtsam::SimpleCamera Lookat(const gtsam::Point3& eye, const gtsam::Point3& target,
|
||||
const gtsam::Point3& upVector, const gtsam::Cal3_S2& K);
|
||||
|
||||
// Testable
|
||||
void print(string s) const;
|
||||
bool equals(const gtsam::SimpleCamera& camera, double tol) const;
|
||||
|
||||
// Standard Interface
|
||||
gtsam::Pose3 pose() const;
|
||||
gtsam::Cal3_S2 calibration() const;
|
||||
|
||||
// Manifold
|
||||
gtsam::SimpleCamera retract(const Vector& d) const;
|
||||
Vector localCoordinates(const gtsam::SimpleCamera& T2) const;
|
||||
size_t dim() const;
|
||||
static size_t Dim();
|
||||
|
||||
// Transformations and measurement functions
|
||||
static gtsam::Point2 Project(const gtsam::Point3& cameraPoint);
|
||||
pair<gtsam::Point2,bool> projectSafe(const gtsam::Point3& pw) const;
|
||||
gtsam::Point2 project(const gtsam::Point3& point);
|
||||
gtsam::Point3 backproject(const gtsam::Point2& p, double depth) const;
|
||||
double range(const gtsam::Point3& point);
|
||||
double range(const gtsam::Pose3& point);
|
||||
|
||||
// enabling serialization functionality
|
||||
void serialize() const;
|
||||
|
||||
};
|
||||
|
||||
// Some typedefs for common camera types
|
||||
// PinholeCameraCal3_S2 is the same as SimpleCamera above
|
||||
typedef gtsam::PinholeCamera<gtsam::Cal3_S2> PinholeCameraCal3_S2;
|
||||
typedef gtsam::PinholeCamera<gtsam::Cal3DS2> PinholeCameraCal3DS2;
|
||||
typedef gtsam::PinholeCamera<gtsam::Cal3Unified> PinholeCameraCal3Unified;
|
||||
typedef gtsam::PinholeCamera<gtsam::Cal3Bundler> PinholeCameraCal3Bundler;
|
||||
|
||||
class StereoCamera {
|
||||
// Standard Constructors and Named Constructors
|
||||
StereoCamera();
|
||||
|
|
@ -877,7 +916,7 @@ class StereoCamera {
|
|||
// Standard Interface
|
||||
gtsam::Pose3 pose() const;
|
||||
double baseline() const;
|
||||
gtsam::Cal3_S2Stereo* calibration() const;
|
||||
gtsam::Cal3_S2Stereo calibration() const;
|
||||
|
||||
// Manifold
|
||||
gtsam::StereoCamera retract(const Vector& d) const;
|
||||
|
|
@ -893,6 +932,16 @@ class StereoCamera {
|
|||
void serialize() const;
|
||||
};
|
||||
|
||||
#include <gtsam/geometry/triangulation.h>
|
||||
|
||||
// Templates appear not yet supported for free functions
|
||||
gtsam::Point3 triangulatePoint3(const gtsam::Pose3Vector& poses,
|
||||
gtsam::Cal3_S2* sharedCal, const gtsam::Point2Vector& measurements,
|
||||
double rank_tol, bool optimize);
|
||||
gtsam::Point3 triangulatePoint3(const gtsam::Pose3Vector& poses,
|
||||
gtsam::Cal3Bundler* sharedCal, const gtsam::Point2Vector& measurements,
|
||||
double rank_tol, bool optimize);
|
||||
|
||||
//*************************************************************************
|
||||
// Symbolic
|
||||
//*************************************************************************
|
||||
|
|
@ -1606,12 +1655,12 @@ char symbolChr(size_t key);
|
|||
size_t symbolIndex(size_t key);
|
||||
|
||||
// Default keyformatter
|
||||
void printKeyList (const gtsam::KeyList& keys);
|
||||
void printKeyList (const gtsam::KeyList& keys, string s);
|
||||
void printKeyVector(const gtsam::KeyVector& keys);
|
||||
void printKeyVector(const gtsam::KeyVector& keys, string s);
|
||||
void printKeySet (const gtsam::KeySet& keys);
|
||||
void printKeySet (const gtsam::KeySet& keys, string s);
|
||||
void PrintKeyList (const gtsam::KeyList& keys);
|
||||
void PrintKeyList (const gtsam::KeyList& keys, string s);
|
||||
void PrintKeyVector(const gtsam::KeyVector& keys);
|
||||
void PrintKeyVector(const gtsam::KeyVector& keys, string s);
|
||||
void PrintKeySet (const gtsam::KeySet& keys);
|
||||
void PrintKeySet (const gtsam::KeySet& keys, string s);
|
||||
|
||||
#include <gtsam/inference/LabeledSymbol.h>
|
||||
class LabeledSymbol {
|
||||
|
|
@ -1728,7 +1777,7 @@ class Values {
|
|||
void swap(gtsam::Values& values);
|
||||
|
||||
bool exists(size_t j) const;
|
||||
gtsam::KeyList keys() const;
|
||||
gtsam::KeyVector keys() const;
|
||||
|
||||
gtsam::VectorValues zeroVectors() const;
|
||||
|
||||
|
|
@ -1845,8 +1894,6 @@ class KeySet {
|
|||
class KeyVector {
|
||||
KeyVector();
|
||||
KeyVector(const gtsam::KeyVector& other);
|
||||
KeyVector(const gtsam::KeySet& other);
|
||||
KeyVector(const gtsam::KeyList& other);
|
||||
|
||||
// Note: no print function
|
||||
|
||||
|
|
@ -2176,9 +2223,6 @@ class NonlinearISAM {
|
|||
//*************************************************************************
|
||||
// Nonlinear factor types
|
||||
//*************************************************************************
|
||||
#include <gtsam/geometry/Cal3_S2.h>
|
||||
#include <gtsam/geometry/Cal3DS2.h>
|
||||
#include <gtsam/geometry/Cal3_S2Stereo.h>
|
||||
#include <gtsam/geometry/SimpleCamera.h>
|
||||
#include <gtsam/geometry/CalibratedCamera.h>
|
||||
#include <gtsam/geometry/StereoPoint2.h>
|
||||
|
|
@ -2219,7 +2263,7 @@ virtual class NonlinearEquality : gtsam::NoiseModelFactor {
|
|||
};
|
||||
|
||||
|
||||
#include <gtsam/slam/RangeFactor.h>
|
||||
#include <gtsam/sam/RangeFactor.h>
|
||||
template<POSE, POINT>
|
||||
virtual class RangeFactor : gtsam::NoiseModelFactor {
|
||||
RangeFactor(size_t key1, size_t key2, double measured, const gtsam::noiseModel::Base* noiseModel);
|
||||
|
|
@ -2229,20 +2273,16 @@ typedef gtsam::RangeFactor<gtsam::Pose2, gtsam::Point2> RangeFactorPosePoint2;
|
|||
typedef gtsam::RangeFactor<gtsam::Pose3, gtsam::Point3> RangeFactorPosePoint3;
|
||||
typedef gtsam::RangeFactor<gtsam::Pose2, gtsam::Pose2> RangeFactorPose2;
|
||||
typedef gtsam::RangeFactor<gtsam::Pose3, gtsam::Pose3> RangeFactorPose3;
|
||||
|
||||
// Commented out by Frank Dec 2014: not poses!
|
||||
// If needed, we need a RangeFactor that takes a camera, extracts the pose
|
||||
// Should be easy with Expressions
|
||||
//typedef gtsam::RangeFactor<gtsam::CalibratedCamera, gtsam::Point3> RangeFactorCalibratedCameraPoint;
|
||||
//typedef gtsam::RangeFactor<gtsam::SimpleCamera, gtsam::Point3> RangeFactorSimpleCameraPoint;
|
||||
//typedef gtsam::RangeFactor<gtsam::CalibratedCamera, gtsam::CalibratedCamera> RangeFactorCalibratedCamera;
|
||||
//typedef gtsam::RangeFactor<gtsam::SimpleCamera, gtsam::SimpleCamera> RangeFactorSimpleCamera;
|
||||
typedef gtsam::RangeFactor<gtsam::CalibratedCamera, gtsam::Point3> RangeFactorCalibratedCameraPoint;
|
||||
typedef gtsam::RangeFactor<gtsam::SimpleCamera, gtsam::Point3> RangeFactorSimpleCameraPoint;
|
||||
typedef gtsam::RangeFactor<gtsam::CalibratedCamera, gtsam::CalibratedCamera> RangeFactorCalibratedCamera;
|
||||
typedef gtsam::RangeFactor<gtsam::SimpleCamera, gtsam::SimpleCamera> RangeFactorSimpleCamera;
|
||||
|
||||
|
||||
#include <gtsam/slam/BearingFactor.h>
|
||||
template<POSE, POINT, ROTATION>
|
||||
#include <gtsam/sam/BearingFactor.h>
|
||||
template<POSE, POINT, BEARING>
|
||||
virtual class BearingFactor : gtsam::NoiseModelFactor {
|
||||
BearingFactor(size_t key1, size_t key2, const ROTATION& measured, const gtsam::noiseModel::Base* noiseModel);
|
||||
BearingFactor(size_t key1, size_t key2, const BEARING& measured, const gtsam::noiseModel::Base* noiseModel);
|
||||
|
||||
// enabling serialization functionality
|
||||
void serialize() const;
|
||||
|
|
@ -2250,19 +2290,18 @@ virtual class BearingFactor : gtsam::NoiseModelFactor {
|
|||
|
||||
typedef gtsam::BearingFactor<gtsam::Pose2, gtsam::Point2, gtsam::Rot2> BearingFactor2D;
|
||||
|
||||
|
||||
#include <gtsam/slam/BearingRangeFactor.h>
|
||||
template<POSE, POINT, ROTATION>
|
||||
#include <gtsam/sam/BearingRangeFactor.h>
|
||||
template<POSE, POINT, BEARING, RANGE>
|
||||
virtual class BearingRangeFactor : gtsam::NoiseModelFactor {
|
||||
BearingRangeFactor(size_t poseKey, size_t pointKey, const ROTATION& measuredBearing, double measuredRange, const gtsam::noiseModel::Base* noiseModel);
|
||||
|
||||
pair<ROTATION, double> measured() const;
|
||||
BearingRangeFactor(size_t poseKey, size_t pointKey,
|
||||
const BEARING& measuredBearing, const RANGE& measuredRange,
|
||||
const gtsam::noiseModel::Base* noiseModel);
|
||||
|
||||
// enabling serialization functionality
|
||||
void serialize() const;
|
||||
};
|
||||
|
||||
typedef gtsam::BearingRangeFactor<gtsam::Pose2, gtsam::Point2, gtsam::Rot2> BearingRangeFactor2D;
|
||||
typedef gtsam::BearingRangeFactor<gtsam::Pose2, gtsam::Point2, gtsam::Rot2, double> BearingRangeFactor2D;
|
||||
|
||||
|
||||
#include <gtsam/slam/ProjectionFactor.h>
|
||||
|
|
@ -2309,24 +2348,39 @@ virtual class GeneralSFMFactor2 : gtsam::NoiseModelFactor {
|
|||
void serialize() const;
|
||||
};
|
||||
|
||||
#include <gtsam/slam/SmartProjectionFactor.h>
|
||||
class SmartProjectionParams {
|
||||
SmartProjectionParams();
|
||||
// TODO(frank): make these work:
|
||||
// void setLinearizationMode(LinearizationMode linMode);
|
||||
// void setDegeneracyMode(DegeneracyMode degMode);
|
||||
void setRankTolerance(double rankTol);
|
||||
void setEnableEPI(bool enableEPI);
|
||||
void setLandmarkDistanceThreshold(bool landmarkDistanceThreshold);
|
||||
void setDynamicOutlierRejectionThreshold(bool dynOutRejectionThreshold);
|
||||
};
|
||||
|
||||
#include <gtsam/slam/SmartProjectionPoseFactor.h>
|
||||
template<POSE, CALIBRATION>
|
||||
virtual class SmartProjectionPoseFactor : gtsam::NonlinearFactor {
|
||||
template<CALIBRATION>
|
||||
virtual class SmartProjectionPoseFactor: gtsam::NonlinearFactor {
|
||||
|
||||
SmartProjectionPoseFactor(double rankTol, double linThreshold,
|
||||
bool manageDegeneracy, bool enableEPI, const POSE& body_P_sensor);
|
||||
SmartProjectionPoseFactor(const gtsam::noiseModel::Base* noise,
|
||||
const CALIBRATION* K);
|
||||
SmartProjectionPoseFactor(const gtsam::noiseModel::Base* noise,
|
||||
const CALIBRATION* K,
|
||||
const gtsam::Pose3& body_P_sensor);
|
||||
SmartProjectionPoseFactor(const gtsam::noiseModel::Base* noise,
|
||||
const CALIBRATION* K,
|
||||
const gtsam::Pose3& body_P_sensor,
|
||||
const gtsam::SmartProjectionParams& params);
|
||||
|
||||
SmartProjectionPoseFactor(double rankTol);
|
||||
SmartProjectionPoseFactor();
|
||||
|
||||
void add(const gtsam::Point2& measured_i, size_t poseKey_i, const gtsam::noiseModel::Base* noise_i,
|
||||
const CALIBRATION* K_i);
|
||||
void add(const gtsam::Point2& measured_i, size_t poseKey_i);
|
||||
|
||||
// enabling serialization functionality
|
||||
//void serialize() const;
|
||||
};
|
||||
|
||||
typedef gtsam::SmartProjectionPoseFactor<gtsam::Pose3, gtsam::Cal3_S2> SmartProjectionPose3Factor;
|
||||
typedef gtsam::SmartProjectionPoseFactor<gtsam::Cal3_S2> SmartProjectionPose3Factor;
|
||||
|
||||
|
||||
#include <gtsam/slam/StereoFactor.h>
|
||||
|
|
@ -2429,18 +2483,18 @@ class ConstantBias {
|
|||
class PoseVelocityBias{
|
||||
PoseVelocityBias(const gtsam::Pose3& pose, Vector velocity, const gtsam::imuBias::ConstantBias& bias);
|
||||
};
|
||||
class ImuFactorPreintegratedMeasurements {
|
||||
class PreintegratedImuMeasurements {
|
||||
// Standard Constructor
|
||||
ImuFactorPreintegratedMeasurements(const gtsam::imuBias::ConstantBias& bias, Matrix measuredAccCovariance,Matrix measuredOmegaCovariance, Matrix integrationErrorCovariance, bool use2ndOrderIntegration);
|
||||
ImuFactorPreintegratedMeasurements(const gtsam::imuBias::ConstantBias& bias, Matrix measuredAccCovariance,Matrix measuredOmegaCovariance, Matrix integrationErrorCovariance);
|
||||
// ImuFactorPreintegratedMeasurements(const gtsam::ImuFactorPreintegratedMeasurements& rhs);
|
||||
PreintegratedImuMeasurements(const gtsam::imuBias::ConstantBias& bias, Matrix measuredAccCovariance,Matrix measuredOmegaCovariance, Matrix integrationErrorCovariance, bool use2ndOrderIntegration);
|
||||
PreintegratedImuMeasurements(const gtsam::imuBias::ConstantBias& bias, Matrix measuredAccCovariance,Matrix measuredOmegaCovariance, Matrix integrationErrorCovariance);
|
||||
// PreintegratedImuMeasurements(const gtsam::PreintegratedImuMeasurements& rhs);
|
||||
|
||||
// Testable
|
||||
void print(string s) const;
|
||||
bool equals(const gtsam::ImuFactorPreintegratedMeasurements& expected, double tol);
|
||||
bool equals(const gtsam::PreintegratedImuMeasurements& expected, double tol);
|
||||
|
||||
double deltaTij() const;
|
||||
Matrix deltaRij() const;
|
||||
gtsam::Rot3 deltaRij() const;
|
||||
Vector deltaPij() const;
|
||||
Vector deltaVij() const;
|
||||
Vector biasHatVector() const;
|
||||
|
|
@ -2453,25 +2507,24 @@ class ImuFactorPreintegratedMeasurements {
|
|||
|
||||
// Standard Interface
|
||||
void integrateMeasurement(Vector measuredAcc, Vector measuredOmega, double deltaT);
|
||||
void integrateMeasurement(Vector measuredAcc, Vector measuredOmega, double deltaT, const gtsam::Pose3& body_P_sensor);
|
||||
gtsam::PoseVelocityBias predict(const gtsam::Pose3& pose_i, Vector vel_i, const gtsam::imuBias::ConstantBias& bias,
|
||||
Vector gravity, Vector omegaCoriolis) const;
|
||||
};
|
||||
|
||||
virtual class ImuFactor : gtsam::NonlinearFactor {
|
||||
ImuFactor(size_t pose_i, size_t vel_i, size_t pose_j, size_t vel_j, size_t bias,
|
||||
const gtsam::ImuFactorPreintegratedMeasurements& preintegratedMeasurements, Vector gravity, Vector omegaCoriolis);
|
||||
const gtsam::PreintegratedImuMeasurements& preintegratedMeasurements, Vector gravity, Vector omegaCoriolis);
|
||||
ImuFactor(size_t pose_i, size_t vel_i, size_t pose_j, size_t vel_j, size_t bias,
|
||||
const gtsam::ImuFactorPreintegratedMeasurements& preintegratedMeasurements, Vector gravity, Vector omegaCoriolis,
|
||||
const gtsam::PreintegratedImuMeasurements& preintegratedMeasurements, Vector gravity, Vector omegaCoriolis,
|
||||
const gtsam::Pose3& body_P_sensor);
|
||||
// Standard Interface
|
||||
gtsam::ImuFactorPreintegratedMeasurements preintegratedMeasurements() const;
|
||||
gtsam::PreintegratedImuMeasurements preintegratedMeasurements() const;
|
||||
};
|
||||
|
||||
#include <gtsam/navigation/CombinedImuFactor.h>
|
||||
class CombinedImuFactorPreintegratedMeasurements {
|
||||
class PreintegratedCombinedMeasurements {
|
||||
// Standard Constructor
|
||||
CombinedImuFactorPreintegratedMeasurements(
|
||||
PreintegratedCombinedMeasurements(
|
||||
const gtsam::imuBias::ConstantBias& bias,
|
||||
Matrix measuredAccCovariance,
|
||||
Matrix measuredOmegaCovariance,
|
||||
|
|
@ -2479,7 +2532,7 @@ class CombinedImuFactorPreintegratedMeasurements {
|
|||
Matrix biasAccCovariance,
|
||||
Matrix biasOmegaCovariance,
|
||||
Matrix biasAccOmegaInit);
|
||||
CombinedImuFactorPreintegratedMeasurements(
|
||||
PreintegratedCombinedMeasurements(
|
||||
const gtsam::imuBias::ConstantBias& bias,
|
||||
Matrix measuredAccCovariance,
|
||||
Matrix measuredOmegaCovariance,
|
||||
|
|
@ -2488,14 +2541,14 @@ class CombinedImuFactorPreintegratedMeasurements {
|
|||
Matrix biasOmegaCovariance,
|
||||
Matrix biasAccOmegaInit,
|
||||
bool use2ndOrderIntegration);
|
||||
// CombinedImuFactorPreintegratedMeasurements(const gtsam::CombinedImuFactorPreintegratedMeasurements& rhs);
|
||||
// PreintegratedCombinedMeasurements(const gtsam::PreintegratedCombinedMeasurements& rhs);
|
||||
|
||||
// Testable
|
||||
void print(string s) const;
|
||||
bool equals(const gtsam::CombinedImuFactorPreintegratedMeasurements& expected, double tol);
|
||||
bool equals(const gtsam::PreintegratedCombinedMeasurements& expected, double tol);
|
||||
|
||||
double deltaTij() const;
|
||||
Matrix deltaRij() const;
|
||||
gtsam::Rot3 deltaRij() const;
|
||||
Vector deltaPij() const;
|
||||
Vector deltaVij() const;
|
||||
Vector biasHatVector() const;
|
||||
|
|
@ -2508,53 +2561,51 @@ class CombinedImuFactorPreintegratedMeasurements {
|
|||
|
||||
// Standard Interface
|
||||
void integrateMeasurement(Vector measuredAcc, Vector measuredOmega, double deltaT);
|
||||
void integrateMeasurement(Vector measuredAcc, Vector measuredOmega, double deltaT, const gtsam::Pose3& body_P_sensor);
|
||||
gtsam::PoseVelocityBias predict(const gtsam::Pose3& pose_i, Vector vel_i, const gtsam::imuBias::ConstantBias& bias,
|
||||
Vector gravity, Vector omegaCoriolis) const;
|
||||
};
|
||||
|
||||
virtual class CombinedImuFactor : gtsam::NonlinearFactor {
|
||||
CombinedImuFactor(size_t pose_i, size_t vel_i, size_t pose_j, size_t vel_j, size_t bias_i, size_t bias_j,
|
||||
const gtsam::CombinedImuFactorPreintegratedMeasurements& CombinedPreintegratedMeasurements, Vector gravity, Vector omegaCoriolis);
|
||||
const gtsam::PreintegratedCombinedMeasurements& CombinedPreintegratedMeasurements, Vector gravity, Vector omegaCoriolis);
|
||||
// Standard Interface
|
||||
gtsam::CombinedImuFactorPreintegratedMeasurements preintegratedMeasurements() const;
|
||||
gtsam::PreintegratedCombinedMeasurements preintegratedMeasurements() const;
|
||||
};
|
||||
|
||||
#include <gtsam/navigation/AHRSFactor.h>
|
||||
class AHRSFactorPreintegratedMeasurements {
|
||||
class PreintegratedAhrsMeasurements {
|
||||
// Standard Constructor
|
||||
AHRSFactorPreintegratedMeasurements(Vector bias, Matrix measuredOmegaCovariance);
|
||||
AHRSFactorPreintegratedMeasurements(Vector bias, Matrix measuredOmegaCovariance);
|
||||
AHRSFactorPreintegratedMeasurements(const gtsam::AHRSFactorPreintegratedMeasurements& rhs);
|
||||
PreintegratedAhrsMeasurements(Vector bias, Matrix measuredOmegaCovariance);
|
||||
PreintegratedAhrsMeasurements(Vector bias, Matrix measuredOmegaCovariance);
|
||||
PreintegratedAhrsMeasurements(const gtsam::PreintegratedAhrsMeasurements& rhs);
|
||||
|
||||
// Testable
|
||||
void print(string s) const;
|
||||
bool equals(const gtsam::AHRSFactorPreintegratedMeasurements& expected, double tol);
|
||||
bool equals(const gtsam::PreintegratedAhrsMeasurements& expected, double tol);
|
||||
|
||||
// get Data
|
||||
Matrix deltaRij() const;
|
||||
gtsam::Rot3 deltaRij() const;
|
||||
double deltaTij() const;
|
||||
Vector biasHat() const;
|
||||
|
||||
// Standard Interface
|
||||
void integrateMeasurement(Vector measuredOmega, double deltaT);
|
||||
void integrateMeasurement(Vector measuredOmega, double deltaT, const gtsam::Pose3& body_P_sensor);
|
||||
void resetIntegration() ;
|
||||
};
|
||||
|
||||
virtual class AHRSFactor : gtsam::NonlinearFactor {
|
||||
AHRSFactor(size_t rot_i, size_t rot_j,size_t bias,
|
||||
const gtsam::AHRSFactorPreintegratedMeasurements& preintegratedMeasurements, Vector omegaCoriolis);
|
||||
const gtsam::PreintegratedAhrsMeasurements& preintegratedMeasurements, Vector omegaCoriolis);
|
||||
AHRSFactor(size_t rot_i, size_t rot_j, size_t bias,
|
||||
const gtsam::AHRSFactorPreintegratedMeasurements& preintegratedMeasurements, Vector omegaCoriolis,
|
||||
const gtsam::PreintegratedAhrsMeasurements& preintegratedMeasurements, Vector omegaCoriolis,
|
||||
const gtsam::Pose3& body_P_sensor);
|
||||
|
||||
// Standard Interface
|
||||
gtsam::AHRSFactorPreintegratedMeasurements preintegratedMeasurements() const;
|
||||
gtsam::PreintegratedAhrsMeasurements preintegratedMeasurements() const;
|
||||
Vector evaluateError(const gtsam::Rot3& rot_i, const gtsam::Rot3& rot_j,
|
||||
Vector bias) const;
|
||||
gtsam::Rot3 predict(const gtsam::Rot3& rot_i, Vector bias,
|
||||
const gtsam::AHRSFactorPreintegratedMeasurements& preintegratedMeasurements,
|
||||
const gtsam::PreintegratedAhrsMeasurements& preintegratedMeasurements,
|
||||
Vector omegaCoriolis) const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -58,10 +58,10 @@ add_subdirectory(ceres)
|
|||
include(GeographicLib/cmake/FindGeographicLib.cmake)
|
||||
|
||||
# Set up the option to install GeographicLib
|
||||
if(GEOGRAPHICLIB_FOUND)
|
||||
set(install_geographiclib_default OFF)
|
||||
else()
|
||||
if(GEOGRAPHICLIB-NOTFOUND)
|
||||
set(install_geographiclib_default ON)
|
||||
else()
|
||||
set(install_geographiclib_default OFF)
|
||||
endif()
|
||||
option(GTSAM_INSTALL_GEOGRAPHICLIB "Build and install the 3rd-party library GeographicLib" ${install_geographiclib_default})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
repo: 8a21fd850624c931e448cbcfb38168cb2717c790
|
||||
node: ffa86ffb557094721ca71dcea6aed2651b9fd610
|
||||
node: c58038c56923e0fd86de3ded18e03df442e66dfb
|
||||
branch: 3.2
|
||||
tag: 3.2.0
|
||||
tag: 3.2.6
|
||||
|
|
|
|||
|
|
@ -23,3 +23,9 @@ bf4cb8c934fa3a79f45f1e629610f0225e93e493 3.1.0-rc2
|
|||
da195914abcc1d739027cbee7c52077aab30b336 3.2-beta1
|
||||
4b687cad1d23066f66863f4f87298447298443df 3.2-rc1
|
||||
1eeda7b1258bcd306018c0738e2b6a8543661141 3.2-rc2
|
||||
ffa86ffb557094721ca71dcea6aed2651b9fd610 3.2.0
|
||||
6b38706d90a9fe182e66ab88477b3dbde34b9f66 3.2.1
|
||||
1306d75b4a21891e59ff9bd96678882cf831e39f 3.2.2
|
||||
36fd1ba04c120cfdd90f3e4cede47f43b21d19ad 3.2.3
|
||||
10219c95fe653d4962aa9db4946f6fbea96dd740 3.2.4
|
||||
bdd17ee3b1b3a166cd5ec36dcad4fc1f3faf774a 3.2.5
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@
|
|||
#undef bool
|
||||
#undef vector
|
||||
#undef pixel
|
||||
#elif defined __ARM_NEON__
|
||||
#elif defined __ARM_NEON
|
||||
#define EIGEN_VECTORIZE
|
||||
#define EIGEN_VECTORIZE_NEON
|
||||
#include <arm_neon.h>
|
||||
|
|
|
|||
|
|
@ -235,6 +235,11 @@ template<typename _MatrixType, int _UpLo> class LDLT
|
|||
}
|
||||
|
||||
protected:
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* Used to compute and store the Cholesky decomposition A = L D L^* = U^* D U.
|
||||
|
|
@ -434,6 +439,8 @@ template<typename MatrixType> struct LDLT_Traits<MatrixType,Upper>
|
|||
template<typename MatrixType, int _UpLo>
|
||||
LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
eigen_assert(a.rows()==a.cols());
|
||||
const Index size = a.rows();
|
||||
|
||||
|
|
@ -442,6 +449,7 @@ LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a)
|
|||
m_transpositions.resize(size);
|
||||
m_isInitialized = false;
|
||||
m_temporary.resize(size);
|
||||
m_sign = internal::ZeroSign;
|
||||
|
||||
internal::ldlt_inplace<UpLo>::unblocked(m_matrix, m_transpositions, m_temporary, m_sign);
|
||||
|
||||
|
|
@ -456,7 +464,7 @@ LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a)
|
|||
*/
|
||||
template<typename MatrixType, int _UpLo>
|
||||
template<typename Derived>
|
||||
LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Derived>& w, const typename NumTraits<typename MatrixType::Scalar>::Real& sigma)
|
||||
LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::rankUpdate(const MatrixBase<Derived>& w, const typename LDLT<MatrixType,_UpLo>::RealScalar& sigma)
|
||||
{
|
||||
const Index size = w.rows();
|
||||
if (m_isInitialized)
|
||||
|
|
@ -502,7 +510,6 @@ struct solve_retval<LDLT<_MatrixType,_UpLo>, Rhs>
|
|||
using std::abs;
|
||||
using std::max;
|
||||
typedef typename LDLTType::MatrixType MatrixType;
|
||||
typedef typename LDLTType::Scalar Scalar;
|
||||
typedef typename LDLTType::RealScalar RealScalar;
|
||||
const typename Diagonal<const MatrixType>::RealReturnType vectorD(dec().vectorD());
|
||||
// In some previous versions, tolerance was set to the max of 1/highest and the maximal diagonal entry * epsilon
|
||||
|
|
|
|||
|
|
@ -174,6 +174,12 @@ template<typename _MatrixType, int _UpLo> class LLT
|
|||
LLT rankUpdate(const VectorType& vec, const RealScalar& sigma = 1);
|
||||
|
||||
protected:
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* Used to compute and store L
|
||||
* The strict upper part is not used and even not initialized.
|
||||
|
|
@ -384,6 +390,8 @@ template<typename MatrixType> struct LLT_Traits<MatrixType,Upper>
|
|||
template<typename MatrixType, int _UpLo>
|
||||
LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const MatrixType& a)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
eigen_assert(a.rows()==a.cols());
|
||||
const Index size = a.rows();
|
||||
m_matrix.resize(size, size);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ template<> struct mkl_llt<EIGTYPE> \
|
|||
lda = m.outerStride(); \
|
||||
\
|
||||
info = LAPACKE_##MKLPREFIX##potrf( matrix_order, uplo, size, (MKLTYPE*)a, lda ); \
|
||||
info = (info==0) ? -1 : 1; \
|
||||
info = (info==0) ? -1 : info>0 ? info-1 : size; \
|
||||
return info; \
|
||||
} \
|
||||
}; \
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ struct traits<ArrayWrapper<ExpressionType> >
|
|||
: public traits<typename remove_all<typename ExpressionType::Nested>::type >
|
||||
{
|
||||
typedef ArrayXpr XprKind;
|
||||
// Let's remove NestByRefBit
|
||||
enum {
|
||||
Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
|
||||
Flags = Flags0 & ~NestByRefBit
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -149,6 +154,11 @@ struct traits<MatrixWrapper<ExpressionType> >
|
|||
: public traits<typename remove_all<typename ExpressionType::Nested>::type >
|
||||
{
|
||||
typedef MatrixXpr XprKind;
|
||||
// Let's remove NestByRefBit
|
||||
enum {
|
||||
Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
|
||||
Flags = Flags0 & ~NestByRefBit
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -439,19 +439,26 @@ struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling, Ve
|
|||
typedef typename Derived1::Index Index;
|
||||
static inline void run(Derived1 &dst, const Derived2 &src)
|
||||
{
|
||||
typedef packet_traits<typename Derived1::Scalar> PacketTraits;
|
||||
typedef typename Derived1::Scalar Scalar;
|
||||
typedef packet_traits<Scalar> PacketTraits;
|
||||
enum {
|
||||
packetSize = PacketTraits::size,
|
||||
alignable = PacketTraits::AlignedOnScalar,
|
||||
dstAlignment = alignable ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) ,
|
||||
dstIsAligned = assign_traits<Derived1,Derived2>::DstIsAligned,
|
||||
dstAlignment = alignable ? Aligned : int(dstIsAligned),
|
||||
srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment
|
||||
};
|
||||
const Scalar *dst_ptr = &dst.coeffRef(0,0);
|
||||
if((!bool(dstIsAligned)) && (size_t(dst_ptr) % sizeof(Scalar))>0)
|
||||
{
|
||||
// the pointer is not aligend-on scalar, so alignment is not possible
|
||||
return assign_impl<Derived1,Derived2,DefaultTraversal,NoUnrolling>::run(dst, src);
|
||||
}
|
||||
const Index packetAlignedMask = packetSize - 1;
|
||||
const Index innerSize = dst.innerSize();
|
||||
const Index outerSize = dst.outerSize();
|
||||
const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0;
|
||||
Index alignedStart = ((!alignable) || assign_traits<Derived1,Derived2>::DstIsAligned) ? 0
|
||||
: internal::first_aligned(&dst.coeffRef(0,0), innerSize);
|
||||
Index alignedStart = ((!alignable) || bool(dstIsAligned)) ? 0 : internal::first_aligned(dst_ptr, innerSize);
|
||||
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,8 +66,9 @@ struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprTyp
|
|||
: ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime)
|
||||
: int(traits<XprType>::MaxColsAtCompileTime),
|
||||
XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
|
||||
IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
|
||||
: (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
||||
IsDense = is_same<StorageKind,Dense>::value,
|
||||
IsRowMajor = (IsDense&&MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
|
||||
: (IsDense&&MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
|
||||
: XprTypeIsRowMajor,
|
||||
HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
|
||||
InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
|
||||
|
|
|
|||
|
|
@ -1,154 +0,0 @@
|
|||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla
|
||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef EIGEN_COMMAINITIALIZER_H
|
||||
#define EIGEN_COMMAINITIALIZER_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
/** \class CommaInitializer
|
||||
* \ingroup Core_Module
|
||||
*
|
||||
* \brief Helper class used by the comma initializer operator
|
||||
*
|
||||
* This class is internally used to implement the comma initializer feature. It is
|
||||
* the return type of MatrixBase::operator<<, and most of the time this is the only
|
||||
* way it is used.
|
||||
*
|
||||
* \sa \ref MatrixBaseCommaInitRef "MatrixBase::operator<<", CommaInitializer::finished()
|
||||
*/
|
||||
template<typename XprType>
|
||||
struct CommaInitializer
|
||||
{
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
typedef typename XprType::Index Index;
|
||||
|
||||
inline CommaInitializer(XprType& xpr, const Scalar& s)
|
||||
: m_xpr(xpr), m_row(0), m_col(1), m_currentBlockRows(1)
|
||||
{
|
||||
m_xpr.coeffRef(0,0) = s;
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
inline CommaInitializer(XprType& xpr, const DenseBase<OtherDerived>& other)
|
||||
: m_xpr(xpr), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows())
|
||||
{
|
||||
m_xpr.block(0, 0, other.rows(), other.cols()) = other;
|
||||
}
|
||||
|
||||
/* Copy/Move constructor which transfers ownership. This is crucial in
|
||||
* absence of return value optimization to avoid assertions during destruction. */
|
||||
// FIXME in C++11 mode this could be replaced by a proper RValue constructor
|
||||
inline CommaInitializer(const CommaInitializer& o)
|
||||
: m_xpr(o.m_xpr), m_row(o.m_row), m_col(o.m_col), m_currentBlockRows(o.m_currentBlockRows) {
|
||||
// Mark original object as finished. In absence of R-value references we need to const_cast:
|
||||
const_cast<CommaInitializer&>(o).m_row = m_xpr.rows();
|
||||
const_cast<CommaInitializer&>(o).m_col = m_xpr.cols();
|
||||
const_cast<CommaInitializer&>(o).m_currentBlockRows = 0;
|
||||
}
|
||||
|
||||
/* inserts a scalar value in the target matrix */
|
||||
CommaInitializer& operator,(const Scalar& s)
|
||||
{
|
||||
if (m_col==m_xpr.cols())
|
||||
{
|
||||
m_row+=m_currentBlockRows;
|
||||
m_col = 0;
|
||||
m_currentBlockRows = 1;
|
||||
eigen_assert(m_row<m_xpr.rows()
|
||||
&& "Too many rows passed to comma initializer (operator<<)");
|
||||
}
|
||||
eigen_assert(m_col<m_xpr.cols()
|
||||
&& "Too many coefficients passed to comma initializer (operator<<)");
|
||||
eigen_assert(m_currentBlockRows==1);
|
||||
m_xpr.coeffRef(m_row, m_col++) = s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* inserts a matrix expression in the target matrix */
|
||||
template<typename OtherDerived>
|
||||
CommaInitializer& operator,(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
if(other.cols()==0 || other.rows()==0)
|
||||
return *this;
|
||||
if (m_col==m_xpr.cols())
|
||||
{
|
||||
m_row+=m_currentBlockRows;
|
||||
m_col = 0;
|
||||
m_currentBlockRows = other.rows();
|
||||
eigen_assert(m_row+m_currentBlockRows<=m_xpr.rows()
|
||||
&& "Too many rows passed to comma initializer (operator<<)");
|
||||
}
|
||||
eigen_assert(m_col<m_xpr.cols()
|
||||
&& "Too many coefficients passed to comma initializer (operator<<)");
|
||||
eigen_assert(m_currentBlockRows==other.rows());
|
||||
if (OtherDerived::SizeAtCompileTime != Dynamic)
|
||||
m_xpr.template block<OtherDerived::RowsAtCompileTime != Dynamic ? OtherDerived::RowsAtCompileTime : 1,
|
||||
OtherDerived::ColsAtCompileTime != Dynamic ? OtherDerived::ColsAtCompileTime : 1>
|
||||
(m_row, m_col) = other;
|
||||
else
|
||||
m_xpr.block(m_row, m_col, other.rows(), other.cols()) = other;
|
||||
m_col += other.cols();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline ~CommaInitializer()
|
||||
{
|
||||
eigen_assert((m_row+m_currentBlockRows) == m_xpr.rows()
|
||||
&& m_col == m_xpr.cols()
|
||||
&& "Too few coefficients passed to comma initializer (operator<<)");
|
||||
}
|
||||
|
||||
/** \returns the built matrix once all its coefficients have been set.
|
||||
* Calling finished is 100% optional. Its purpose is to write expressions
|
||||
* like this:
|
||||
* \code
|
||||
* quaternion.fromRotationMatrix((Matrix3f() << axis0, axis1, axis2).finished());
|
||||
* \endcode
|
||||
*/
|
||||
inline XprType& finished() { return m_xpr; }
|
||||
|
||||
XprType& m_xpr; // target expression
|
||||
Index m_row; // current row id
|
||||
Index m_col; // current col id
|
||||
Index m_currentBlockRows; // current block height
|
||||
};
|
||||
|
||||
/** \anchor MatrixBaseCommaInitRef
|
||||
* Convenient operator to set the coefficients of a matrix.
|
||||
*
|
||||
* The coefficients must be provided in a row major order and exactly match
|
||||
* the size of the matrix. Otherwise an assertion is raised.
|
||||
*
|
||||
* Example: \include MatrixBase_set.cpp
|
||||
* Output: \verbinclude MatrixBase_set.out
|
||||
*
|
||||
* \note According the c++ standard, the argument expressions of this comma initializer are evaluated in arbitrary order.
|
||||
*
|
||||
* \sa CommaInitializer::finished(), class CommaInitializer
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline CommaInitializer<Derived> DenseBase<Derived>::operator<< (const Scalar& s)
|
||||
{
|
||||
return CommaInitializer<Derived>(*static_cast<Derived*>(this), s);
|
||||
}
|
||||
|
||||
/** \sa operator<<(const Scalar&) */
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline CommaInitializer<Derived>
|
||||
DenseBase<Derived>::operator<<(const DenseBase<OtherDerived>& other)
|
||||
{
|
||||
return CommaInitializer<Derived>(*static_cast<Derived *>(this), other);
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_COMMAINITIALIZER_H
|
||||
|
|
@ -183,10 +183,6 @@ template<typename Derived> class DenseBase
|
|||
/** \returns the number of nonzero coefficients which is in practice the number
|
||||
* of stored coefficients. */
|
||||
inline Index nonZeros() const { return size(); }
|
||||
/** \returns true if either the number of rows or the number of columns is equal to 1.
|
||||
* In other words, this function returns
|
||||
* \code rows()==1 || cols()==1 \endcode
|
||||
* \sa rows(), cols(), IsVectorAtCompileTime. */
|
||||
|
||||
/** \returns the outer size.
|
||||
*
|
||||
|
|
@ -266,11 +262,13 @@ template<typename Derived> class DenseBase
|
|||
template<typename OtherDerived>
|
||||
Derived& operator=(const ReturnByValue<OtherDerived>& func);
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
/** Copies \a other into *this without evaluating other. \returns a reference to *this. */
|
||||
/** \internal Copies \a other into *this without evaluating other. \returns a reference to *this. */
|
||||
template<typename OtherDerived>
|
||||
Derived& lazyAssign(const DenseBase<OtherDerived>& other);
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
/** \internal Evaluates \a other into *this. \returns a reference to *this. */
|
||||
template<typename OtherDerived>
|
||||
Derived& lazyAssign(const ReturnByValue<OtherDerived>& other);
|
||||
|
||||
CommaInitializer<Derived> operator<< (const Scalar& s);
|
||||
|
||||
|
|
@ -462,8 +460,10 @@ template<typename Derived> class DenseBase
|
|||
template<int p> RealScalar lpNorm() const;
|
||||
|
||||
template<int RowFactor, int ColFactor>
|
||||
const Replicate<Derived,RowFactor,ColFactor> replicate() const;
|
||||
const Replicate<Derived,Dynamic,Dynamic> replicate(Index rowFacor,Index colFactor) const;
|
||||
inline const Replicate<Derived,RowFactor,ColFactor> replicate() const;
|
||||
|
||||
typedef Replicate<Derived,Dynamic,Dynamic> ReplicateReturnType;
|
||||
inline const ReplicateReturnType replicate(Index rowFacor,Index colFactor) const;
|
||||
|
||||
typedef Reverse<Derived, BothDirections> ReverseReturnType;
|
||||
typedef const Reverse<const Derived, BothDirections> ConstReverseReturnType;
|
||||
|
|
|
|||
|
|
@ -190,18 +190,18 @@ MatrixBase<Derived>::diagonal() const
|
|||
*
|
||||
* \sa MatrixBase::diagonal(), class Diagonal */
|
||||
template<typename Derived>
|
||||
inline typename MatrixBase<Derived>::template DiagonalIndexReturnType<DynamicIndex>::Type
|
||||
inline typename MatrixBase<Derived>::DiagonalDynamicIndexReturnType
|
||||
MatrixBase<Derived>::diagonal(Index index)
|
||||
{
|
||||
return typename DiagonalIndexReturnType<DynamicIndex>::Type(derived(), index);
|
||||
return DiagonalDynamicIndexReturnType(derived(), index);
|
||||
}
|
||||
|
||||
/** This is the const version of diagonal(Index). */
|
||||
template<typename Derived>
|
||||
inline typename MatrixBase<Derived>::template ConstDiagonalIndexReturnType<DynamicIndex>::Type
|
||||
inline typename MatrixBase<Derived>::ConstDiagonalDynamicIndexReturnType
|
||||
MatrixBase<Derived>::diagonal(Index index) const
|
||||
{
|
||||
return typename ConstDiagonalIndexReturnType<DynamicIndex>::Type(derived(), index);
|
||||
return ConstDiagonalDynamicIndexReturnType(derived(), index);
|
||||
}
|
||||
|
||||
/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ struct traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> >
|
|||
_Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))),
|
||||
_LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0,
|
||||
|
||||
Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0) | AlignedBit,//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit),
|
||||
Flags = ((HereditaryBits|_LinearAccessMask|AlignedBit) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0),//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit),
|
||||
CoeffReadCost = NumTraits<Scalar>::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -259,6 +259,47 @@ template<> struct functor_traits<scalar_boolean_or_op> {
|
|||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functors for comparison of two scalars
|
||||
* \todo Implement packet-comparisons
|
||||
*/
|
||||
template<typename Scalar, ComparisonName cmp> struct scalar_cmp_op;
|
||||
|
||||
template<typename Scalar, ComparisonName cmp>
|
||||
struct functor_traits<scalar_cmp_op<Scalar, cmp> > {
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::AddCost,
|
||||
PacketAccess = false
|
||||
};
|
||||
};
|
||||
|
||||
template<ComparisonName Cmp, typename Scalar>
|
||||
struct result_of<scalar_cmp_op<Scalar, Cmp>(Scalar,Scalar)> {
|
||||
typedef bool type;
|
||||
};
|
||||
|
||||
|
||||
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_EQ> {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
|
||||
EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a==b;}
|
||||
};
|
||||
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LT> {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
|
||||
EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<b;}
|
||||
};
|
||||
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LE> {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
|
||||
EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<=b;}
|
||||
};
|
||||
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_UNORD> {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
|
||||
EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return !(a<=b || b<=a);}
|
||||
};
|
||||
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_NEQ> {
|
||||
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
|
||||
EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a!=b;}
|
||||
};
|
||||
|
||||
// unary functors:
|
||||
|
||||
/** \internal
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest&
|
|||
// FIXME not very good if rhs is real and lhs complex while alpha is real too
|
||||
const Index cols = dest.cols();
|
||||
for (Index j=0; j<cols; ++j)
|
||||
func(dest.col(j), prod.rhs().coeff(j) * prod.lhs());
|
||||
func(dest.col(j), prod.rhs().coeff(0,j) * prod.lhs());
|
||||
}
|
||||
|
||||
// Row major
|
||||
|
|
@ -243,7 +243,7 @@ EIGEN_DONT_INLINE void outer_product_selector_run(const ProductType& prod, Dest&
|
|||
// FIXME not very good if lhs is real and rhs complex while alpha is real too
|
||||
const Index rows = dest.rows();
|
||||
for (Index i=0; i<rows; ++i)
|
||||
func(dest.row(i), prod.lhs().coeff(i) * prod.rhs());
|
||||
func(dest.row(i), prod.lhs().coeff(i,0) * prod.rhs());
|
||||
}
|
||||
|
||||
template<typename Lhs, typename Rhs>
|
||||
|
|
@ -257,7 +257,7 @@ template<typename Lhs, typename Rhs>
|
|||
class GeneralProduct<Lhs, Rhs, OuterProduct>
|
||||
: public ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs>
|
||||
{
|
||||
template<typename T> struct IsRowMajor : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {};
|
||||
template<typename T> struct is_row_major : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {};
|
||||
|
||||
public:
|
||||
EIGEN_PRODUCT_PUBLIC_INTERFACE(GeneralProduct)
|
||||
|
|
@ -281,22 +281,22 @@ class GeneralProduct<Lhs, Rhs, OuterProduct>
|
|||
|
||||
template<typename Dest>
|
||||
inline void evalTo(Dest& dest) const {
|
||||
internal::outer_product_selector_run(*this, dest, set(), IsRowMajor<Dest>());
|
||||
internal::outer_product_selector_run(*this, dest, set(), is_row_major<Dest>());
|
||||
}
|
||||
|
||||
template<typename Dest>
|
||||
inline void addTo(Dest& dest) const {
|
||||
internal::outer_product_selector_run(*this, dest, add(), IsRowMajor<Dest>());
|
||||
internal::outer_product_selector_run(*this, dest, add(), is_row_major<Dest>());
|
||||
}
|
||||
|
||||
template<typename Dest>
|
||||
inline void subTo(Dest& dest) const {
|
||||
internal::outer_product_selector_run(*this, dest, sub(), IsRowMajor<Dest>());
|
||||
internal::outer_product_selector_run(*this, dest, sub(), is_row_major<Dest>());
|
||||
}
|
||||
|
||||
template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
|
||||
{
|
||||
internal::outer_product_selector_run(*this, dest, adds(alpha), IsRowMajor<Dest>());
|
||||
internal::outer_product_selector_run(*this, dest, adds(alpha), is_row_major<Dest>());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
|||
return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride());
|
||||
}
|
||||
|
||||
inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
|
||||
explicit inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||
checkSanity();
|
||||
|
|
@ -157,7 +157,7 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
|||
internal::inner_stride_at_compile_time<Derived>::ret==1),
|
||||
PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1);
|
||||
eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::Flags&AlignedBit, (size_t(m_data) % 16) == 0)
|
||||
&& "data is not aligned");
|
||||
&& "input pointer is not aligned on a 16 byte boundary");
|
||||
}
|
||||
|
||||
PointerType m_data;
|
||||
|
|
@ -168,6 +168,7 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
|||
template<typename Derived> class MapBase<Derived, WriteAccessors>
|
||||
: public MapBase<Derived, ReadOnlyAccessors>
|
||||
{
|
||||
typedef MapBase<Derived, ReadOnlyAccessors> ReadOnlyMapBase;
|
||||
public:
|
||||
|
||||
typedef MapBase<Derived, ReadOnlyAccessors> Base;
|
||||
|
|
@ -230,11 +231,13 @@ template<typename Derived> class MapBase<Derived, WriteAccessors>
|
|||
|
||||
Derived& operator=(const MapBase& other)
|
||||
{
|
||||
Base::Base::operator=(other);
|
||||
ReadOnlyMapBase::Base::operator=(other);
|
||||
return derived();
|
||||
}
|
||||
|
||||
using Base::Base::operator=;
|
||||
// In theory we could simply refer to Base:Base::operator=, but MSVC does not like Base::Base,
|
||||
// see bugs 821 and 920.
|
||||
using ReadOnlyMapBase::Base::operator=;
|
||||
};
|
||||
|
||||
#undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ struct hypot_impl
|
|||
RealScalar _x = abs(x);
|
||||
RealScalar _y = abs(y);
|
||||
RealScalar p = (max)(_x, _y);
|
||||
if(p==RealScalar(0)) return 0;
|
||||
if(p==RealScalar(0)) return RealScalar(0);
|
||||
RealScalar q = (min)(_x, _y);
|
||||
RealScalar qp = q/p;
|
||||
return p * sqrt(RealScalar(1) + qp*qp);
|
||||
|
|
|
|||
|
|
@ -159,13 +159,11 @@ template<typename Derived> class MatrixBase
|
|||
template<typename OtherDerived>
|
||||
Derived& operator=(const ReturnByValue<OtherDerived>& other);
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
||||
Derived& lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other);
|
||||
|
||||
template<typename MatrixPower, typename Lhs, typename Rhs>
|
||||
Derived& lazyAssign(const MatrixPowerProduct<MatrixPower, Lhs,Rhs>& other);
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
template<typename OtherDerived>
|
||||
Derived& operator+=(const MatrixBase<OtherDerived>& other);
|
||||
|
|
@ -215,7 +213,7 @@ template<typename Derived> class MatrixBase
|
|||
|
||||
typedef Diagonal<Derived> DiagonalReturnType;
|
||||
DiagonalReturnType diagonal();
|
||||
typedef typename internal::add_const<Diagonal<const Derived> >::type ConstDiagonalReturnType;
|
||||
typedef typename internal::add_const<Diagonal<const Derived> >::type ConstDiagonalReturnType;
|
||||
ConstDiagonalReturnType diagonal() const;
|
||||
|
||||
template<int Index> struct DiagonalIndexReturnType { typedef Diagonal<Derived,Index> Type; };
|
||||
|
|
@ -223,16 +221,12 @@ template<typename Derived> class MatrixBase
|
|||
|
||||
template<int Index> typename DiagonalIndexReturnType<Index>::Type diagonal();
|
||||
template<int Index> typename ConstDiagonalIndexReturnType<Index>::Type diagonal() const;
|
||||
|
||||
typedef Diagonal<Derived,DynamicIndex> DiagonalDynamicIndexReturnType;
|
||||
typedef typename internal::add_const<Diagonal<const Derived,DynamicIndex> >::type ConstDiagonalDynamicIndexReturnType;
|
||||
|
||||
// Note: The "MatrixBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations.
|
||||
// On the other hand they confuse MSVC8...
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1500) // 2008 or later
|
||||
typename MatrixBase::template DiagonalIndexReturnType<DynamicIndex>::Type diagonal(Index index);
|
||||
typename MatrixBase::template ConstDiagonalIndexReturnType<DynamicIndex>::Type diagonal(Index index) const;
|
||||
#else
|
||||
typename DiagonalIndexReturnType<DynamicIndex>::Type diagonal(Index index);
|
||||
typename ConstDiagonalIndexReturnType<DynamicIndex>::Type diagonal(Index index) const;
|
||||
#endif
|
||||
DiagonalDynamicIndexReturnType diagonal(Index index);
|
||||
ConstDiagonalDynamicIndexReturnType diagonal(Index index) const;
|
||||
|
||||
#ifdef EIGEN2_SUPPORT
|
||||
template<unsigned int Mode> typename internal::eigen2_part_return_type<Derived, Mode>::type part();
|
||||
|
|
|
|||
|
|
@ -250,6 +250,35 @@ class PermutationBase : public EigenBase<Derived>
|
|||
template<typename Other> friend
|
||||
inline PlainPermutationType operator*(const Transpose<PermutationBase<Other> >& other, const PermutationBase& perm)
|
||||
{ return PlainPermutationType(internal::PermPermProduct, other.eval(), perm); }
|
||||
|
||||
/** \returns the determinant of the permutation matrix, which is either 1 or -1 depending on the parity of the permutation.
|
||||
*
|
||||
* This function is O(\c n) procedure allocating a buffer of \c n booleans.
|
||||
*/
|
||||
Index determinant() const
|
||||
{
|
||||
Index res = 1;
|
||||
Index n = size();
|
||||
Matrix<bool,RowsAtCompileTime,1,0,MaxRowsAtCompileTime> mask(n);
|
||||
mask.fill(false);
|
||||
Index r = 0;
|
||||
while(r < n)
|
||||
{
|
||||
// search for the next seed
|
||||
while(r<n && mask[r]) r++;
|
||||
if(r>=n)
|
||||
break;
|
||||
// we got one, let's follow it until we are back to the seed
|
||||
Index k0 = r++;
|
||||
mask.coeffRef(k0) = true;
|
||||
for(Index k=indices().coeff(k0); k!=k0; k=indices().coeff(k))
|
||||
{
|
||||
mask.coeffRef(k) = true;
|
||||
res = -res;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
|
@ -555,7 +584,10 @@ struct permut_matrix_product_retval
|
|||
const Index n = Side==OnTheLeft ? rows() : cols();
|
||||
// FIXME we need an is_same for expression that is not sensitive to constness. For instance
|
||||
// is_same_xpr<Block<const Matrix>, Block<Matrix> >::value should be true.
|
||||
if(is_same<MatrixTypeNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_matrix))
|
||||
if( is_same<MatrixTypeNestedCleaned,Dest>::value
|
||||
&& blas_traits<MatrixTypeNestedCleaned>::HasUsableDirectAccess
|
||||
&& blas_traits<Dest>::HasUsableDirectAccess
|
||||
&& extract_data(dst) == extract_data(m_matrix))
|
||||
{
|
||||
// apply the permutation inplace
|
||||
Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(m_permutation.size());
|
||||
|
|
|
|||
|
|
@ -437,6 +437,22 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||
}
|
||||
#endif
|
||||
|
||||
/** Copy constructor */
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
|
||||
: m_storage()
|
||||
{
|
||||
_check_template_params();
|
||||
lazyAssign(other);
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
|
||||
: m_storage()
|
||||
{
|
||||
_check_template_params();
|
||||
lazyAssign(other);
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols)
|
||||
: m_storage(a_size, nbRows, nbCols)
|
||||
{
|
||||
|
|
@ -573,6 +589,8 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||
: (rows() == other.rows() && cols() == other.cols())))
|
||||
&& "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(other);
|
||||
if(this->size()==0)
|
||||
resizeLike(other);
|
||||
#else
|
||||
resizeLike(other);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -85,7 +85,14 @@ class ProductBase : public MatrixBase<Derived>
|
|||
|
||||
public:
|
||||
|
||||
#ifndef EIGEN_NO_MALLOC
|
||||
typedef typename Base::PlainObject BasePlainObject;
|
||||
typedef Matrix<Scalar,RowsAtCompileTime==1?1:Dynamic,ColsAtCompileTime==1?1:Dynamic,BasePlainObject::Options> DynPlainObject;
|
||||
typedef typename internal::conditional<(BasePlainObject::SizeAtCompileTime==Dynamic) || (BasePlainObject::SizeAtCompileTime*int(sizeof(Scalar)) < int(EIGEN_STACK_ALLOCATION_LIMIT)),
|
||||
BasePlainObject, DynPlainObject>::type PlainObject;
|
||||
#else
|
||||
typedef typename Base::PlainObject PlainObject;
|
||||
#endif
|
||||
|
||||
ProductBase(const Lhs& a_lhs, const Rhs& a_rhs)
|
||||
: m_lhs(a_lhs), m_rhs(a_rhs)
|
||||
|
|
@ -180,7 +187,12 @@ namespace internal {
|
|||
template<typename Lhs, typename Rhs, int Mode, int N, typename PlainObject>
|
||||
struct nested<GeneralProduct<Lhs,Rhs,Mode>, N, PlainObject>
|
||||
{
|
||||
typedef PlainObject const& type;
|
||||
typedef typename GeneralProduct<Lhs,Rhs,Mode>::PlainObject const& type;
|
||||
};
|
||||
template<typename Lhs, typename Rhs, int Mode, int N, typename PlainObject>
|
||||
struct nested<const GeneralProduct<Lhs,Rhs,Mode>, N, PlainObject>
|
||||
{
|
||||
typedef typename GeneralProduct<Lhs,Rhs,Mode>::PlainObject const& type;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,8 @@ struct traits<Ref<_PlainObjectType, _Options, _StrideType> >
|
|||
OuterStrideMatch = Derived::IsVectorAtCompileTime
|
||||
|| int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime),
|
||||
AlignmentMatch = (_Options!=Aligned) || ((PlainObjectType::Flags&AlignedBit)==0) || ((traits<Derived>::Flags&AlignedBit)==AlignedBit),
|
||||
MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch
|
||||
ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value,
|
||||
MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch
|
||||
};
|
||||
typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
|
||||
};
|
||||
|
|
@ -187,7 +188,11 @@ protected:
|
|||
template<typename PlainObjectType, int Options, typename StrideType> class Ref
|
||||
: public RefBase<Ref<PlainObjectType, Options, StrideType> >
|
||||
{
|
||||
private:
|
||||
typedef internal::traits<Ref> Traits;
|
||||
template<typename Derived>
|
||||
inline Ref(const PlainObjectBase<Derived>& expr,
|
||||
typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0);
|
||||
public:
|
||||
|
||||
typedef RefBase<Ref> Base;
|
||||
|
|
@ -199,17 +204,20 @@ template<typename PlainObjectType, int Options, typename StrideType> class Ref
|
|||
inline Ref(PlainObjectBase<Derived>& expr,
|
||||
typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
|
||||
{
|
||||
Base::construct(expr);
|
||||
EIGEN_STATIC_ASSERT(static_cast<bool>(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
||||
Base::construct(expr.derived());
|
||||
}
|
||||
template<typename Derived>
|
||||
inline Ref(const DenseBase<Derived>& expr,
|
||||
typename internal::enable_if<bool(internal::is_lvalue<Derived>::value&&bool(Traits::template match<Derived>::MatchAtCompileTime)),Derived>::type* = 0,
|
||||
int = Derived::ThisConstantIsPrivateInPlainObjectBase)
|
||||
typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
|
||||
#else
|
||||
template<typename Derived>
|
||||
inline Ref(DenseBase<Derived>& expr)
|
||||
#endif
|
||||
{
|
||||
EIGEN_STATIC_ASSERT(static_cast<bool>(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||
EIGEN_STATIC_ASSERT(static_cast<bool>(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
||||
enum { THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY = Derived::ThisConstantIsPrivateInPlainObjectBase};
|
||||
Base::construct(expr.const_cast_derived());
|
||||
}
|
||||
|
||||
|
|
@ -228,13 +236,23 @@ template<typename TPlainObjectType, int Options, typename StrideType> class Ref<
|
|||
EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
|
||||
|
||||
template<typename Derived>
|
||||
inline Ref(const DenseBase<Derived>& expr)
|
||||
inline Ref(const DenseBase<Derived>& expr,
|
||||
typename internal::enable_if<bool(Traits::template match<Derived>::ScalarTypeMatch),Derived>::type* = 0)
|
||||
{
|
||||
// std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n";
|
||||
// std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n";
|
||||
// std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n";
|
||||
construct(expr.derived(), typename Traits::template match<Derived>::type());
|
||||
}
|
||||
|
||||
inline Ref(const Ref& other) : Base(other) {
|
||||
// copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
|
||||
}
|
||||
|
||||
template<typename OtherRef>
|
||||
inline Ref(const RefBase<OtherRef>& other) {
|
||||
construct(other.derived(), typename Traits::template match<OtherRef>::type());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
|
|||
*/
|
||||
template<typename Derived>
|
||||
template<int RowFactor, int ColFactor>
|
||||
inline const Replicate<Derived,RowFactor,ColFactor>
|
||||
const Replicate<Derived,RowFactor,ColFactor>
|
||||
DenseBase<Derived>::replicate() const
|
||||
{
|
||||
return Replicate<Derived,RowFactor,ColFactor>(derived());
|
||||
|
|
@ -150,7 +150,7 @@ DenseBase<Derived>::replicate() const
|
|||
* \sa VectorwiseOp::replicate(), DenseBase::replicate<int,int>(), class Replicate
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline const Replicate<Derived,Dynamic,Dynamic>
|
||||
const typename DenseBase<Derived>::ReplicateReturnType
|
||||
DenseBase<Derived>::replicate(Index rowFactor,Index colFactor) const
|
||||
{
|
||||
return Replicate<Derived,Dynamic,Dynamic>(derived(),rowFactor,colFactor);
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ template<typename Derived> class ReturnByValue
|
|||
const Unusable& coeff(Index,Index) const { return *reinterpret_cast<const Unusable*>(this); }
|
||||
Unusable& coeffRef(Index) { return *reinterpret_cast<Unusable*>(this); }
|
||||
Unusable& coeffRef(Index,Index) { return *reinterpret_cast<Unusable*>(this); }
|
||||
template<int LoadMode> Unusable& packet(Index) const;
|
||||
template<int LoadMode> Unusable& packet(Index, Index) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -83,6 +85,15 @@ Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
|
|||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
Derived& DenseBase<Derived>::lazyAssign(const ReturnByValue<OtherDerived>& other)
|
||||
{
|
||||
other.evalTo(derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_RETURNBYVALUE_H
|
||||
|
|
|
|||
|
|
@ -380,19 +380,19 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
|||
EIGEN_STRONG_INLINE TriangularView& operator=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
|
||||
{
|
||||
setZero();
|
||||
return assignProduct(other,1);
|
||||
return assignProduct(other.derived(),1);
|
||||
}
|
||||
|
||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
||||
EIGEN_STRONG_INLINE TriangularView& operator+=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
|
||||
{
|
||||
return assignProduct(other,1);
|
||||
return assignProduct(other.derived(),1);
|
||||
}
|
||||
|
||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
||||
EIGEN_STRONG_INLINE TriangularView& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
|
||||
{
|
||||
return assignProduct(other,-1);
|
||||
return assignProduct(other.derived(),-1);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -400,25 +400,34 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
|
|||
EIGEN_STRONG_INLINE TriangularView& operator=(const ScaledProduct<ProductDerived>& other)
|
||||
{
|
||||
setZero();
|
||||
return assignProduct(other,other.alpha());
|
||||
return assignProduct(other.derived(),other.alpha());
|
||||
}
|
||||
|
||||
template<typename ProductDerived>
|
||||
EIGEN_STRONG_INLINE TriangularView& operator+=(const ScaledProduct<ProductDerived>& other)
|
||||
{
|
||||
return assignProduct(other,other.alpha());
|
||||
return assignProduct(other.derived(),other.alpha());
|
||||
}
|
||||
|
||||
template<typename ProductDerived>
|
||||
EIGEN_STRONG_INLINE TriangularView& operator-=(const ScaledProduct<ProductDerived>& other)
|
||||
{
|
||||
return assignProduct(other,-other.alpha());
|
||||
return assignProduct(other.derived(),-other.alpha());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
template<typename ProductDerived, typename Lhs, typename Rhs>
|
||||
EIGEN_STRONG_INLINE TriangularView& assignProduct(const ProductBase<ProductDerived, Lhs,Rhs>& prod, const Scalar& alpha);
|
||||
|
||||
template<int Mode, bool LhsIsTriangular,
|
||||
typename Lhs, bool LhsIsVector,
|
||||
typename Rhs, bool RhsIsVector>
|
||||
EIGEN_STRONG_INLINE TriangularView& assignProduct(const TriangularProduct<Mode, LhsIsTriangular, Lhs, LhsIsVector, Rhs, RhsIsVector>& prod, const Scalar& alpha)
|
||||
{
|
||||
lazyAssign(alpha*prod.eval());
|
||||
return *this;
|
||||
}
|
||||
|
||||
MatrixTypeNested m_matrix;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ template<> EIGEN_STRONG_INLINE Packet2cf ploaddup<Packet2cf>(const std::complex<
|
|||
template<> EIGEN_STRONG_INLINE void pstore <std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); }
|
||||
template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<float> >(std::complex<float> * to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> * addr) { __pld((float *)addr); }
|
||||
template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> * addr) { EIGEN_ARM_PREFETCH((float *)addr); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet2cf>(const Packet2cf& a)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,9 +48,18 @@ typedef uint32x4_t Packet4ui;
|
|||
#define EIGEN_INIT_NEON_PACKET2(X, Y) {X, Y}
|
||||
#define EIGEN_INIT_NEON_PACKET4(X, Y, Z, W) {X, Y, Z, W}
|
||||
#endif
|
||||
|
||||
#ifndef __pld
|
||||
#define __pld(x) asm volatile ( " pld [%[addr]]\n" :: [addr] "r" (x) : "cc" );
|
||||
|
||||
// arm64 does have the pld instruction. If available, let's trust the __builtin_prefetch built-in function
|
||||
// which available on LLVM and GCC (at least)
|
||||
#if EIGEN_HAS_BUILTIN(__builtin_prefetch) || defined(__GNUC__)
|
||||
#define EIGEN_ARM_PREFETCH(ADDR) __builtin_prefetch(ADDR);
|
||||
#elif defined __pld
|
||||
#define EIGEN_ARM_PREFETCH(ADDR) __pld(ADDR)
|
||||
#elif !defined(__aarch64__)
|
||||
#define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__ ( " pld [%[addr]]\n" :: [addr] "r" (ADDR) : "cc" );
|
||||
#else
|
||||
// by default no explicit prefetching
|
||||
#define EIGEN_ARM_PREFETCH(ADDR)
|
||||
#endif
|
||||
|
||||
template<> struct packet_traits<float> : default_packet_traits
|
||||
|
|
@ -209,8 +218,8 @@ template<> EIGEN_STRONG_INLINE void pstore<int>(int* to, const Packet4i& f
|
|||
template<> EIGEN_STRONG_INLINE void pstoreu<float>(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_f32(to, from); }
|
||||
template<> EIGEN_STRONG_INLINE void pstoreu<int>(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE vst1q_s32(to, from); }
|
||||
|
||||
template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { __pld(addr); }
|
||||
template<> EIGEN_STRONG_INLINE void prefetch<int>(const int* addr) { __pld(addr); }
|
||||
template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { EIGEN_ARM_PREFETCH(addr); }
|
||||
template<> EIGEN_STRONG_INLINE void prefetch<int>(const int* addr) { EIGEN_ARM_PREFETCH(addr); }
|
||||
|
||||
// FIXME only store the 2 first elements ?
|
||||
template<> EIGEN_STRONG_INLINE float pfirst<Packet4f>(const Packet4f& a) { float EIGEN_ALIGN16 x[4]; vst1q_f32(x, a); return x[0]; }
|
||||
|
|
@ -375,6 +384,7 @@ template<> EIGEN_STRONG_INLINE int predux_max<Packet4i>(const Packet4i& a)
|
|||
a_lo = vget_low_s32(a);
|
||||
a_hi = vget_high_s32(a);
|
||||
max = vpmax_s32(a_lo, a_hi);
|
||||
max = vpmax_s32(max, max);
|
||||
|
||||
return vget_lane_s32(max, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ Packet4f plog<Packet4f>(const Packet4f& _x)
|
|||
|
||||
Packet4i emm0;
|
||||
|
||||
Packet4f invalid_mask = _mm_cmplt_ps(x, _mm_setzero_ps());
|
||||
Packet4f invalid_mask = _mm_cmpnge_ps(x, _mm_setzero_ps()); // not greater equal is true if x is NaN
|
||||
Packet4f iszero_mask = _mm_cmpeq_ps(x, _mm_setzero_ps());
|
||||
|
||||
x = pmax(x, p4f_min_norm_pos); /* cut off denormalized stuff */
|
||||
|
|
@ -166,7 +166,7 @@ Packet4f pexp<Packet4f>(const Packet4f& _x)
|
|||
emm0 = _mm_cvttps_epi32(fx);
|
||||
emm0 = _mm_add_epi32(emm0, p4i_0x7f);
|
||||
emm0 = _mm_slli_epi32(emm0, 23);
|
||||
return pmul(y, _mm_castsi128_ps(emm0));
|
||||
return pmax(pmul(y, Packet4f(_mm_castsi128_ps(emm0))), _x);
|
||||
}
|
||||
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED
|
||||
Packet2d pexp<Packet2d>(const Packet2d& _x)
|
||||
|
|
@ -239,7 +239,7 @@ Packet2d pexp<Packet2d>(const Packet2d& _x)
|
|||
emm0 = _mm_add_epi32(emm0, p4i_1023_0);
|
||||
emm0 = _mm_slli_epi32(emm0, 20);
|
||||
emm0 = _mm_shuffle_epi32(emm0, _MM_SHUFFLE(1,2,0,3));
|
||||
return pmul(x, _mm_castsi128_pd(emm0));
|
||||
return pmax(pmul(x, Packet2d(_mm_castsi128_pd(emm0))), _x);
|
||||
}
|
||||
|
||||
/* evaluation of 4 sines at onces, using SSE2 intrinsics.
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ struct traits<CoeffBasedProduct<LhsNested,RhsNested,NestingFlags> >
|
|||
| (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0),
|
||||
|
||||
CoeffReadCost = InnerSize == Dynamic ? Dynamic
|
||||
: InnerSize == 0 ? 0
|
||||
: InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost)
|
||||
+ (InnerSize - 1) * NumTraits<Scalar>::AddCost,
|
||||
|
||||
|
|
@ -133,7 +134,7 @@ class CoeffBasedProduct
|
|||
};
|
||||
|
||||
typedef internal::product_coeff_impl<CanVectorizeInner ? InnerVectorizedTraversal : DefaultTraversal,
|
||||
Unroll ? InnerSize-1 : Dynamic,
|
||||
Unroll ? InnerSize : Dynamic,
|
||||
_LhsNested, _RhsNested, Scalar> ScalarCoeffImpl;
|
||||
|
||||
typedef CoeffBasedProduct<LhsNested,RhsNested,NestByRefBit> LazyCoeffBasedProductType;
|
||||
|
|
@ -184,7 +185,7 @@ class CoeffBasedProduct
|
|||
{
|
||||
PacketScalar res;
|
||||
internal::product_packet_impl<Flags&RowMajorBit ? RowMajor : ColMajor,
|
||||
Unroll ? InnerSize-1 : Dynamic,
|
||||
Unroll ? InnerSize : Dynamic,
|
||||
_LhsNested, _RhsNested, PacketScalar, LoadMode>
|
||||
::run(row, col, m_lhs, m_rhs, res);
|
||||
return res;
|
||||
|
|
@ -242,12 +243,12 @@ struct product_coeff_impl<DefaultTraversal, UnrollingIndex, Lhs, Rhs, RetScalar>
|
|||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
|
||||
{
|
||||
product_coeff_impl<DefaultTraversal, UnrollingIndex-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res);
|
||||
res += lhs.coeff(row, UnrollingIndex) * rhs.coeff(UnrollingIndex, col);
|
||||
res += lhs.coeff(row, UnrollingIndex-1) * rhs.coeff(UnrollingIndex-1, col);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
||||
struct product_coeff_impl<DefaultTraversal, 0, Lhs, Rhs, RetScalar>
|
||||
struct product_coeff_impl<DefaultTraversal, 1, Lhs, Rhs, RetScalar>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
|
||||
|
|
@ -256,16 +257,23 @@ struct product_coeff_impl<DefaultTraversal, 0, Lhs, Rhs, RetScalar>
|
|||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
||||
struct product_coeff_impl<DefaultTraversal, 0, Lhs, Rhs, RetScalar>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, RetScalar &res)
|
||||
{
|
||||
res = RetScalar(0);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
||||
struct product_coeff_impl<DefaultTraversal, Dynamic, Lhs, Rhs, RetScalar>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar& res)
|
||||
{
|
||||
eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix");
|
||||
res = lhs.coeff(row, 0) * rhs.coeff(0, col);
|
||||
for(Index i = 1; i < lhs.cols(); ++i)
|
||||
res += lhs.coeff(row, i) * rhs.coeff(i, col);
|
||||
res = (lhs.row(row).transpose().cwiseProduct( rhs.col(col) )).sum();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -295,6 +303,16 @@ struct product_coeff_vectorized_unroller<0, Lhs, Rhs, Packet>
|
|||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename RetScalar>
|
||||
struct product_coeff_impl<InnerVectorizedTraversal, 0, Lhs, Rhs, RetScalar>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, RetScalar &res)
|
||||
{
|
||||
res = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar>
|
||||
struct product_coeff_impl<InnerVectorizedTraversal, UnrollingIndex, Lhs, Rhs, RetScalar>
|
||||
{
|
||||
|
|
@ -304,8 +322,7 @@ struct product_coeff_impl<InnerVectorizedTraversal, UnrollingIndex, Lhs, Rhs, Re
|
|||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)
|
||||
{
|
||||
Packet pres;
|
||||
product_coeff_vectorized_unroller<UnrollingIndex+1-PacketSize, Lhs, Rhs, Packet>::run(row, col, lhs, rhs, pres);
|
||||
product_coeff_impl<DefaultTraversal,UnrollingIndex,Lhs,Rhs,RetScalar>::run(row, col, lhs, rhs, res);
|
||||
product_coeff_vectorized_unroller<UnrollingIndex-PacketSize, Lhs, Rhs, Packet>::run(row, col, lhs, rhs, pres);
|
||||
res = predux(pres);
|
||||
}
|
||||
};
|
||||
|
|
@ -373,7 +390,7 @@ struct product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
|||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res)
|
||||
{
|
||||
product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, res);
|
||||
res = pmadd(pset1<Packet>(lhs.coeff(row, UnrollingIndex)), rhs.template packet<LoadMode>(UnrollingIndex, col), res);
|
||||
res = pmadd(pset1<Packet>(lhs.coeff(row, UnrollingIndex-1)), rhs.template packet<LoadMode>(UnrollingIndex-1, col), res);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -384,12 +401,12 @@ struct product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
|
|||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res)
|
||||
{
|
||||
product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, res);
|
||||
res = pmadd(lhs.template packet<LoadMode>(row, UnrollingIndex), pset1<Packet>(rhs.coeff(UnrollingIndex, col)), res);
|
||||
res = pmadd(lhs.template packet<LoadMode>(row, UnrollingIndex-1), pset1<Packet>(rhs.coeff(UnrollingIndex-1, col)), res);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||
struct product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
||||
struct product_packet_impl<RowMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res)
|
||||
|
|
@ -399,7 +416,7 @@ struct product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
|||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||
struct product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
||||
struct product_packet_impl<ColMajor, 1, Lhs, Rhs, Packet, LoadMode>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res)
|
||||
|
|
@ -408,16 +425,35 @@ struct product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
|||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||
struct product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Packet &res)
|
||||
{
|
||||
res = pset1<Packet>(0);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||
struct product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Packet &res)
|
||||
{
|
||||
res = pset1<Packet>(0);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
|
||||
struct product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
||||
{
|
||||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res)
|
||||
{
|
||||
eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix");
|
||||
res = pmul(pset1<Packet>(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col));
|
||||
for(Index i = 1; i < lhs.cols(); ++i)
|
||||
res = pmadd(pset1<Packet>(lhs.coeff(row, i)), rhs.template packet<LoadMode>(i, col), res);
|
||||
res = pset1<Packet>(0);
|
||||
for(Index i = 0; i < lhs.cols(); ++i)
|
||||
res = pmadd(pset1<Packet>(lhs.coeff(row, i)), rhs.template packet<LoadMode>(i, col), res);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -427,10 +463,9 @@ struct product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
|
|||
typedef typename Lhs::Index Index;
|
||||
static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res)
|
||||
{
|
||||
eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix");
|
||||
res = pmul(lhs.template packet<LoadMode>(row, 0), pset1<Packet>(rhs.coeff(0, col)));
|
||||
for(Index i = 1; i < lhs.cols(); ++i)
|
||||
res = pmadd(lhs.template packet<LoadMode>(row, i), pset1<Packet>(rhs.coeff(i, col)), res);
|
||||
res = pset1<Packet>(0);
|
||||
for(Index i = 0; i < lhs.cols(); ++i)
|
||||
res = pmadd(lhs.template packet<LoadMode>(row, i), pset1<Packet>(rhs.coeff(i, col)), res);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -125,19 +125,22 @@ void parallelize_gemm(const Functor& func, Index rows, Index cols, bool transpos
|
|||
if(transpose)
|
||||
std::swap(rows,cols);
|
||||
|
||||
Index blockCols = (cols / threads) & ~Index(0x3);
|
||||
Index blockRows = (rows / threads) & ~Index(0x7);
|
||||
|
||||
GemmParallelInfo<Index>* info = new GemmParallelInfo<Index>[threads];
|
||||
|
||||
#pragma omp parallel for schedule(static,1) num_threads(threads)
|
||||
for(Index i=0; i<threads; ++i)
|
||||
#pragma omp parallel num_threads(threads)
|
||||
{
|
||||
Index i = omp_get_thread_num();
|
||||
// Note that the actual number of threads might be lower than the number of request ones.
|
||||
Index actual_threads = omp_get_num_threads();
|
||||
|
||||
Index blockCols = (cols / actual_threads) & ~Index(0x3);
|
||||
Index blockRows = (rows / actual_threads) & ~Index(0x7);
|
||||
|
||||
Index r0 = i*blockRows;
|
||||
Index actualBlockRows = (i+1==threads) ? rows-r0 : blockRows;
|
||||
Index actualBlockRows = (i+1==actual_threads) ? rows-r0 : blockRows;
|
||||
|
||||
Index c0 = i*blockCols;
|
||||
Index actualBlockCols = (i+1==threads) ? cols-c0 : blockCols;
|
||||
Index actualBlockCols = (i+1==actual_threads) ? cols-c0 : blockCols;
|
||||
|
||||
info[i].rhs_start = c0;
|
||||
info[i].rhs_length = actualBlockCols;
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,true, \
|
|||
/* Non-square case - doesn't fit to MKL ?TRMM. Fall to default triangular product or call MKL ?GEMM*/ \
|
||||
if (rows != depth) { \
|
||||
\
|
||||
int nthr = mkl_domain_get_max_threads(MKL_BLAS); \
|
||||
int nthr = mkl_domain_get_max_threads(EIGEN_MKL_DOMAIN_BLAS); \
|
||||
\
|
||||
if (((nthr==1) && (((std::max)(rows,depth)-diagSize)/(double)diagSize < 0.5))) { \
|
||||
/* Most likely no benefit to call TRMM or GEMM from MKL*/ \
|
||||
|
|
@ -223,7 +223,7 @@ struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,false, \
|
|||
/* Non-square case - doesn't fit to MKL ?TRMM. Fall to default triangular product or call MKL ?GEMM*/ \
|
||||
if (cols != depth) { \
|
||||
\
|
||||
int nthr = mkl_domain_get_max_threads(MKL_BLAS); \
|
||||
int nthr = mkl_domain_get_max_threads(EIGEN_MKL_DOMAIN_BLAS); \
|
||||
\
|
||||
if ((nthr==1) && (((std::max)(cols,depth)-diagSize)/(double)diagSize < 0.5)) { \
|
||||
/* Most likely no benefit to call TRMM or GEMM from MKL*/ \
|
||||
|
|
|
|||
|
|
@ -433,6 +433,19 @@ struct MatrixXpr {};
|
|||
/** The type used to identify an array expression */
|
||||
struct ArrayXpr {};
|
||||
|
||||
namespace internal {
|
||||
/** \internal
|
||||
* Constants for comparison functors
|
||||
*/
|
||||
enum ComparisonName {
|
||||
cmp_EQ = 0,
|
||||
cmp_LT = 1,
|
||||
cmp_LE = 2,
|
||||
cmp_UNORD = 3,
|
||||
cmp_NEQ = 4
|
||||
};
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_CONSTANTS_H
|
||||
|
|
|
|||
|
|
@ -76,6 +76,38 @@
|
|||
#include <mkl_lapacke.h>
|
||||
#define EIGEN_MKL_VML_THRESHOLD 128
|
||||
|
||||
/* MKL_DOMAIN_BLAS, etc are defined only in 10.3 update 7 */
|
||||
/* MKL_BLAS, etc are not defined in 11.2 */
|
||||
#ifdef MKL_DOMAIN_ALL
|
||||
#define EIGEN_MKL_DOMAIN_ALL MKL_DOMAIN_ALL
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_ALL MKL_ALL
|
||||
#endif
|
||||
|
||||
#ifdef MKL_DOMAIN_BLAS
|
||||
#define EIGEN_MKL_DOMAIN_BLAS MKL_DOMAIN_BLAS
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_BLAS MKL_BLAS
|
||||
#endif
|
||||
|
||||
#ifdef MKL_DOMAIN_FFT
|
||||
#define EIGEN_MKL_DOMAIN_FFT MKL_DOMAIN_FFT
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_FFT MKL_FFT
|
||||
#endif
|
||||
|
||||
#ifdef MKL_DOMAIN_VML
|
||||
#define EIGEN_MKL_DOMAIN_VML MKL_DOMAIN_VML
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_VML MKL_VML
|
||||
#endif
|
||||
|
||||
#ifdef MKL_DOMAIN_PARDISO
|
||||
#define EIGEN_MKL_DOMAIN_PARDISO MKL_DOMAIN_PARDISO
|
||||
#else
|
||||
#define EIGEN_MKL_DOMAIN_PARDISO MKL_PARDISO
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
typedef std::complex<double> dcomplex;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#define EIGEN_WORLD_VERSION 3
|
||||
#define EIGEN_MAJOR_VERSION 2
|
||||
#define EIGEN_MINOR_VERSION 2
|
||||
#define EIGEN_MINOR_VERSION 6
|
||||
|
||||
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
|
||||
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
|
||||
|
|
@ -96,6 +96,13 @@
|
|||
#define EIGEN_DEFAULT_DENSE_INDEX_TYPE std::ptrdiff_t
|
||||
#endif
|
||||
|
||||
// Cross compiler wrapper around LLVM's __has_builtin
|
||||
#ifdef __has_builtin
|
||||
# define EIGEN_HAS_BUILTIN(x) __has_builtin(x)
|
||||
#else
|
||||
# define EIGEN_HAS_BUILTIN(x) 0
|
||||
#endif
|
||||
|
||||
/** Allows to disable some optimizations which might affect the accuracy of the result.
|
||||
* Such optimization are enabled by default, and set EIGEN_FAST_MATH to 0 to disable them.
|
||||
* They currently include:
|
||||
|
|
@ -247,7 +254,7 @@ namespace Eigen {
|
|||
|
||||
#if !defined(EIGEN_ASM_COMMENT)
|
||||
#if (defined __GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
|
||||
#define EIGEN_ASM_COMMENT(X) asm("#" X)
|
||||
#define EIGEN_ASM_COMMENT(X) __asm__("#" X)
|
||||
#else
|
||||
#define EIGEN_ASM_COMMENT(X)
|
||||
#endif
|
||||
|
|
@ -271,6 +278,7 @@ namespace Eigen {
|
|||
#error Please tell me what is the equivalent of __attribute__((aligned(n))) for your compiler
|
||||
#endif
|
||||
|
||||
#define EIGEN_ALIGN8 EIGEN_ALIGN_TO_BOUNDARY(8)
|
||||
#define EIGEN_ALIGN16 EIGEN_ALIGN_TO_BOUNDARY(16)
|
||||
|
||||
#if EIGEN_ALIGN_STATICALLY
|
||||
|
|
@ -306,7 +314,7 @@ namespace Eigen {
|
|||
// just an empty macro !
|
||||
#define EIGEN_EMPTY
|
||||
|
||||
#if defined(_MSC_VER) && (!defined(__INTEL_COMPILER))
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900) && (!defined(__INTEL_COMPILER))
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
|
||||
using Base::operator =;
|
||||
#elif defined(__clang__) // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
|
||||
|
|
@ -325,8 +333,11 @@ namespace Eigen {
|
|||
}
|
||||
#endif
|
||||
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \
|
||||
EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived)
|
||||
/** \internal
|
||||
* \brief Macro to manually inherit assignment operators.
|
||||
* This is necessary, because the implicitly defined assignment operator gets deleted when a custom operator= is defined.
|
||||
*/
|
||||
#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived)
|
||||
|
||||
/**
|
||||
* Just a side note. Commenting within defines works only by documenting
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@
|
|||
// Currently, let's include it only on unix systems:
|
||||
#if defined(__unix__) || defined(__unix)
|
||||
#include <unistd.h>
|
||||
#if ((defined __QNXNTO__) || (defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
|
||||
#if ((defined __QNXNTO__) || (defined _GNU_SOURCE) || (defined __PGI) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
|
||||
#define EIGEN_HAS_POSIX_MEMALIGN 1
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -417,6 +417,8 @@ template<typename T, bool Align> inline T* conditional_aligned_realloc_new(T* pt
|
|||
|
||||
template<typename T, bool Align> inline T* conditional_aligned_new_auto(size_t size)
|
||||
{
|
||||
if(size==0)
|
||||
return 0; // short-cut. Also fixes Bug 884
|
||||
check_size_for_overflow<T>(size);
|
||||
T *result = reinterpret_cast<T*>(conditional_aligned_malloc<Align>(sizeof(T)*size));
|
||||
if(NumTraits<T>::RequireInitialization)
|
||||
|
|
@ -464,9 +466,8 @@ template<typename T, bool Align> inline void conditional_aligned_delete_auto(T *
|
|||
template<typename Scalar, typename Index>
|
||||
static inline Index first_aligned(const Scalar* array, Index size)
|
||||
{
|
||||
enum { PacketSize = packet_traits<Scalar>::size,
|
||||
PacketAlignedMask = PacketSize-1
|
||||
};
|
||||
static const Index PacketSize = packet_traits<Scalar>::size;
|
||||
static const Index PacketAlignedMask = PacketSize-1;
|
||||
|
||||
if(PacketSize==1)
|
||||
{
|
||||
|
|
@ -522,7 +523,7 @@ template<typename T> struct smart_copy_helper<T,false> {
|
|||
// you can overwrite Eigen's default behavior regarding alloca by defining EIGEN_ALLOCA
|
||||
// to the appropriate stack allocation function
|
||||
#ifndef EIGEN_ALLOCA
|
||||
#if (defined __linux__)
|
||||
#if (defined __linux__) || (defined __APPLE__) || (defined alloca)
|
||||
#define EIGEN_ALLOCA alloca
|
||||
#elif defined(_MSC_VER)
|
||||
#define EIGEN_ALLOCA _alloca
|
||||
|
|
@ -612,7 +613,6 @@ template<typename T> class aligned_stack_memory_handler
|
|||
void* operator new(size_t size, const std::nothrow_t&) throw() { \
|
||||
try { return Eigen::internal::conditional_aligned_malloc<NeedsToAlign>(size); } \
|
||||
catch (...) { return 0; } \
|
||||
return 0; \
|
||||
}
|
||||
#else
|
||||
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
|
||||
|
|
|
|||
|
|
@ -90,7 +90,9 @@
|
|||
YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED,
|
||||
THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE,
|
||||
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH,
|
||||
OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG
|
||||
OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG,
|
||||
IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY,
|
||||
STORAGE_LAYOUT_DOES_NOT_MATCH
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ template<typename T, int n=1, typename PlainObject = typename eval<T>::type> str
|
|||
};
|
||||
|
||||
template<typename T>
|
||||
T* const_cast_ptr(const T* ptr)
|
||||
inline T* const_cast_ptr(const T* ptr)
|
||||
{
|
||||
return const_cast<T*>(ptr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,7 +147,6 @@ void fitHyperplane(int numPoints,
|
|||
|
||||
// compute the covariance matrix
|
||||
CovMatrixType covMat = CovMatrixType::Zero(size, size);
|
||||
VectorType remean = VectorType::Zero(size);
|
||||
for(int i = 0; i < numPoints; ++i)
|
||||
{
|
||||
VectorType diff = (*(points[i]) - mean).conjugate();
|
||||
|
|
|
|||
|
|
@ -234,6 +234,12 @@ template<typename _MatrixType> class ComplexEigenSolver
|
|||
}
|
||||
|
||||
protected:
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
EigenvectorType m_eivec;
|
||||
EigenvalueType m_eivalues;
|
||||
ComplexSchur<MatrixType> m_schur;
|
||||
|
|
@ -251,6 +257,8 @@ template<typename MatrixType>
|
|||
ComplexEigenSolver<MatrixType>&
|
||||
ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
// this code is inspired from Jampack
|
||||
eigen_assert(matrix.cols() == matrix.rows());
|
||||
|
||||
|
|
|
|||
|
|
@ -298,6 +298,13 @@ template<typename _MatrixType> class EigenSolver
|
|||
void doComputeEigenvectors();
|
||||
|
||||
protected:
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL);
|
||||
}
|
||||
|
||||
MatrixType m_eivec;
|
||||
EigenvalueType m_eivalues;
|
||||
bool m_isInitialized;
|
||||
|
|
@ -364,6 +371,8 @@ template<typename MatrixType>
|
|||
EigenSolver<MatrixType>&
|
||||
EigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
using std::sqrt;
|
||||
using std::abs;
|
||||
eigen_assert(matrix.cols() == matrix.rows());
|
||||
|
|
|
|||
|
|
@ -263,6 +263,13 @@ template<typename _MatrixType> class GeneralizedEigenSolver
|
|||
}
|
||||
|
||||
protected:
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL);
|
||||
}
|
||||
|
||||
MatrixType m_eivec;
|
||||
ComplexVectorType m_alphas;
|
||||
VectorType m_betas;
|
||||
|
|
@ -290,6 +297,8 @@ template<typename MatrixType>
|
|||
GeneralizedEigenSolver<MatrixType>&
|
||||
GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
using std::sqrt;
|
||||
using std::abs;
|
||||
eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows());
|
||||
|
|
|
|||
|
|
@ -240,10 +240,10 @@ namespace Eigen {
|
|||
m_S.coeffRef(i,j) = Scalar(0.0);
|
||||
m_S.rightCols(dim-j-1).applyOnTheLeft(i-1,i,G.adjoint());
|
||||
m_T.rightCols(dim-i+1).applyOnTheLeft(i-1,i,G.adjoint());
|
||||
// update Q
|
||||
if (m_computeQZ)
|
||||
m_Q.applyOnTheRight(i-1,i,G);
|
||||
}
|
||||
// update Q
|
||||
if (m_computeQZ)
|
||||
m_Q.applyOnTheRight(i-1,i,G);
|
||||
// kill T(i,i-1)
|
||||
if(m_T.coeff(i,i-1)!=Scalar(0))
|
||||
{
|
||||
|
|
@ -251,10 +251,10 @@ namespace Eigen {
|
|||
m_T.coeffRef(i,i-1) = Scalar(0.0);
|
||||
m_S.applyOnTheRight(i,i-1,G);
|
||||
m_T.topRows(i).applyOnTheRight(i,i-1,G);
|
||||
// update Z
|
||||
if (m_computeQZ)
|
||||
m_Z.applyOnTheLeft(i,i-1,G.adjoint());
|
||||
}
|
||||
// update Z
|
||||
if (m_computeQZ)
|
||||
m_Z.applyOnTheLeft(i,i-1,G.adjoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -313,7 +313,7 @@ namespace Eigen {
|
|||
using std::abs;
|
||||
using std::sqrt;
|
||||
const Index dim=m_S.cols();
|
||||
if (abs(m_S.coeff(i+1,i)==Scalar(0)))
|
||||
if (abs(m_S.coeff(i+1,i))==Scalar(0))
|
||||
return;
|
||||
Index z = findSmallDiagEntry(i,i+1);
|
||||
if (z==i-1)
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ template<typename _MatrixType> class RealSchur
|
|||
typedef Matrix<Scalar,3,1> Vector3s;
|
||||
|
||||
Scalar computeNormOfT();
|
||||
Index findSmallSubdiagEntry(Index iu, const Scalar& norm);
|
||||
Index findSmallSubdiagEntry(Index iu);
|
||||
void splitOffTwoRows(Index iu, bool computeU, const Scalar& exshift);
|
||||
void computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo);
|
||||
void initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector);
|
||||
|
|
@ -286,7 +286,7 @@ RealSchur<MatrixType>& RealSchur<MatrixType>::computeFromHessenberg(const HessMa
|
|||
{
|
||||
while (iu >= 0)
|
||||
{
|
||||
Index il = findSmallSubdiagEntry(iu, norm);
|
||||
Index il = findSmallSubdiagEntry(iu);
|
||||
|
||||
// Check for convergence
|
||||
if (il == iu) // One root found
|
||||
|
|
@ -343,16 +343,14 @@ inline typename MatrixType::Scalar RealSchur<MatrixType>::computeNormOfT()
|
|||
|
||||
/** \internal Look for single small sub-diagonal element and returns its index */
|
||||
template<typename MatrixType>
|
||||
inline typename MatrixType::Index RealSchur<MatrixType>::findSmallSubdiagEntry(Index iu, const Scalar& norm)
|
||||
inline typename MatrixType::Index RealSchur<MatrixType>::findSmallSubdiagEntry(Index iu)
|
||||
{
|
||||
using std::abs;
|
||||
Index res = iu;
|
||||
while (res > 0)
|
||||
{
|
||||
Scalar s = abs(m_matT.coeff(res-1,res-1)) + abs(m_matT.coeff(res,res));
|
||||
if (s == 0.0)
|
||||
s = norm;
|
||||
if (abs(m_matT.coeff(res,res-1)) < NumTraits<Scalar>::epsilon() * s)
|
||||
if (abs(m_matT.coeff(res,res-1)) <= NumTraits<Scalar>::epsilon() * s)
|
||||
break;
|
||||
res--;
|
||||
}
|
||||
|
|
@ -457,9 +455,7 @@ inline void RealSchur<MatrixType>::initFrancisQRStep(Index il, Index iu, const V
|
|||
const Scalar lhs = m_matT.coeff(im,im-1) * (abs(v.coeff(1)) + abs(v.coeff(2)));
|
||||
const Scalar rhs = v.coeff(0) * (abs(m_matT.coeff(im-1,im-1)) + abs(Tmm) + abs(m_matT.coeff(im+1,im+1)));
|
||||
if (abs(lhs) < NumTraits<Scalar>::epsilon() * rhs)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
|||
/** \brief Scalar type for matrices of type \p _MatrixType. */
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
|
||||
typedef Matrix<Scalar,Size,Size,ColMajor,MaxColsAtCompileTime,MaxColsAtCompileTime> EigenvectorsType;
|
||||
|
||||
/** \brief Real scalar type for \p _MatrixType.
|
||||
*
|
||||
|
|
@ -225,7 +227,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
|||
*
|
||||
* \sa eigenvalues()
|
||||
*/
|
||||
const MatrixType& eigenvectors() const
|
||||
const EigenvectorsType& eigenvectors() const
|
||||
{
|
||||
eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");
|
||||
eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");
|
||||
|
|
@ -351,7 +353,12 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
|||
#endif // EIGEN2_SUPPORT
|
||||
|
||||
protected:
|
||||
MatrixType m_eivec;
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
EigenvectorsType m_eivec;
|
||||
RealVectorType m_eivalues;
|
||||
typename TridiagonalizationType::SubDiagonalType m_subdiag;
|
||||
ComputationInfo m_info;
|
||||
|
|
@ -376,7 +383,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver
|
|||
* "implicit symmetric QR step with Wilkinson shift"
|
||||
*/
|
||||
namespace internal {
|
||||
template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
|
||||
template<typename RealScalar, typename Scalar, typename Index>
|
||||
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n);
|
||||
}
|
||||
|
||||
|
|
@ -384,6 +391,8 @@ template<typename MatrixType>
|
|||
SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
||||
::compute(const MatrixType& matrix, int options)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
using std::abs;
|
||||
eigen_assert(matrix.cols() == matrix.rows());
|
||||
eigen_assert((options&~(EigVecMask|GenEigMask))==0
|
||||
|
|
@ -406,7 +415,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
|||
|
||||
// declare some aliases
|
||||
RealVectorType& diag = m_eivalues;
|
||||
MatrixType& mat = m_eivec;
|
||||
EigenvectorsType& mat = m_eivec;
|
||||
|
||||
// map the matrix coefficients to [-1:1] to avoid over- and underflow.
|
||||
mat = matrix.template triangularView<Lower>();
|
||||
|
|
@ -442,7 +451,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
|||
while (start>0 && m_subdiag[start-1]!=0)
|
||||
start--;
|
||||
|
||||
internal::tridiagonal_qr_step<MatrixType::Flags&RowMajorBit ? RowMajor : ColMajor>(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n);
|
||||
internal::tridiagonal_qr_step(diag.data(), m_subdiag.data(), start, end, computeEigenvectors ? m_eivec.data() : (Scalar*)0, n);
|
||||
}
|
||||
|
||||
if (iter <= m_maxIterations * n)
|
||||
|
|
@ -490,7 +499,13 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,3
|
|||
typedef typename SolverType::MatrixType MatrixType;
|
||||
typedef typename SolverType::RealVectorType VectorType;
|
||||
typedef typename SolverType::Scalar Scalar;
|
||||
typedef typename MatrixType::Index Index;
|
||||
typedef typename SolverType::EigenvectorsType EigenvectorsType;
|
||||
|
||||
/** \internal
|
||||
* Computes the roots of the characteristic polynomial of \a m.
|
||||
* For numerical stability m.trace() should be near zero and to avoid over- or underflow m should be normalized.
|
||||
*/
|
||||
static inline void computeRoots(const MatrixType& m, VectorType& roots)
|
||||
{
|
||||
using std::sqrt;
|
||||
|
|
@ -510,148 +525,123 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,3
|
|||
// Construct the parameters used in classifying the roots of the equation
|
||||
// and in solving the equation for the roots in closed form.
|
||||
Scalar c2_over_3 = c2*s_inv3;
|
||||
Scalar a_over_3 = (c1 - c2*c2_over_3)*s_inv3;
|
||||
if (a_over_3 > Scalar(0))
|
||||
Scalar a_over_3 = (c2*c2_over_3 - c1)*s_inv3;
|
||||
if(a_over_3<Scalar(0))
|
||||
a_over_3 = Scalar(0);
|
||||
|
||||
Scalar half_b = Scalar(0.5)*(c0 + c2_over_3*(Scalar(2)*c2_over_3*c2_over_3 - c1));
|
||||
|
||||
Scalar q = half_b*half_b + a_over_3*a_over_3*a_over_3;
|
||||
if (q > Scalar(0))
|
||||
Scalar q = a_over_3*a_over_3*a_over_3 - half_b*half_b;
|
||||
if(q<Scalar(0))
|
||||
q = Scalar(0);
|
||||
|
||||
// Compute the eigenvalues by solving for the roots of the polynomial.
|
||||
Scalar rho = sqrt(-a_over_3);
|
||||
Scalar theta = atan2(sqrt(-q),half_b)*s_inv3;
|
||||
Scalar rho = sqrt(a_over_3);
|
||||
Scalar theta = atan2(sqrt(q),half_b)*s_inv3; // since sqrt(q) > 0, atan2 is in [0, pi] and theta is in [0, pi/3]
|
||||
Scalar cos_theta = cos(theta);
|
||||
Scalar sin_theta = sin(theta);
|
||||
roots(0) = c2_over_3 + Scalar(2)*rho*cos_theta;
|
||||
roots(1) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta);
|
||||
roots(2) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta);
|
||||
|
||||
// Sort in increasing order.
|
||||
if (roots(0) >= roots(1))
|
||||
std::swap(roots(0),roots(1));
|
||||
if (roots(1) >= roots(2))
|
||||
{
|
||||
std::swap(roots(1),roots(2));
|
||||
if (roots(0) >= roots(1))
|
||||
std::swap(roots(0),roots(1));
|
||||
}
|
||||
// roots are already sorted, since cos is monotonically decreasing on [0, pi]
|
||||
roots(0) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta); // == 2*rho*cos(theta+2pi/3)
|
||||
roots(1) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta); // == 2*rho*cos(theta+ pi/3)
|
||||
roots(2) = c2_over_3 + Scalar(2)*rho*cos_theta;
|
||||
}
|
||||
|
||||
|
||||
static inline bool extract_kernel(MatrixType& mat, Ref<VectorType> res, Ref<VectorType> representative)
|
||||
{
|
||||
using std::abs;
|
||||
Index i0;
|
||||
// Find non-zero column i0 (by construction, there must exist a non zero coefficient on the diagonal):
|
||||
mat.diagonal().cwiseAbs().maxCoeff(&i0);
|
||||
// mat.col(i0) is a good candidate for an orthogonal vector to the current eigenvector,
|
||||
// so let's save it:
|
||||
representative = mat.col(i0);
|
||||
Scalar n0, n1;
|
||||
VectorType c0, c1;
|
||||
n0 = (c0 = representative.cross(mat.col((i0+1)%3))).squaredNorm();
|
||||
n1 = (c1 = representative.cross(mat.col((i0+2)%3))).squaredNorm();
|
||||
if(n0>n1) res = c0/std::sqrt(n0);
|
||||
else res = c1/std::sqrt(n1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void run(SolverType& solver, const MatrixType& mat, int options)
|
||||
{
|
||||
using std::sqrt;
|
||||
eigen_assert(mat.cols() == 3 && mat.cols() == mat.rows());
|
||||
eigen_assert((options&~(EigVecMask|GenEigMask))==0
|
||||
&& (options&EigVecMask)!=EigVecMask
|
||||
&& "invalid option parameter");
|
||||
bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
|
||||
|
||||
MatrixType& eivecs = solver.m_eivec;
|
||||
EigenvectorsType& eivecs = solver.m_eivec;
|
||||
VectorType& eivals = solver.m_eivalues;
|
||||
|
||||
// map the matrix coefficients to [-1:1] to avoid over- and underflow.
|
||||
Scalar scale = mat.cwiseAbs().maxCoeff();
|
||||
MatrixType scaledMat = mat / scale;
|
||||
// Shift the matrix to the mean eigenvalue and map the matrix coefficients to [-1:1] to avoid over- and underflow.
|
||||
Scalar shift = mat.trace() / Scalar(3);
|
||||
// TODO Avoid this copy. Currently it is necessary to suppress bogus values when determining maxCoeff and for computing the eigenvectors later
|
||||
MatrixType scaledMat = mat.template selfadjointView<Lower>();
|
||||
scaledMat.diagonal().array() -= shift;
|
||||
Scalar scale = scaledMat.cwiseAbs().maxCoeff();
|
||||
if(scale > 0) scaledMat /= scale; // TODO for scale==0 we could save the remaining operations
|
||||
|
||||
// compute the eigenvalues
|
||||
computeRoots(scaledMat,eivals);
|
||||
|
||||
// compute the eigen vectors
|
||||
// compute the eigenvectors
|
||||
if(computeEigenvectors)
|
||||
{
|
||||
Scalar safeNorm2 = Eigen::NumTraits<Scalar>::epsilon();
|
||||
safeNorm2 *= safeNorm2;
|
||||
if((eivals(2)-eivals(0))<=Eigen::NumTraits<Scalar>::epsilon())
|
||||
{
|
||||
// All three eigenvalues are numerically the same
|
||||
eivecs.setIdentity();
|
||||
}
|
||||
else
|
||||
{
|
||||
scaledMat = scaledMat.template selfadjointView<Lower>();
|
||||
MatrixType tmp;
|
||||
tmp = scaledMat;
|
||||
|
||||
// Compute the eigenvector of the most distinct eigenvalue
|
||||
Scalar d0 = eivals(2) - eivals(1);
|
||||
Scalar d1 = eivals(1) - eivals(0);
|
||||
int k = d0 > d1 ? 2 : 0;
|
||||
d0 = d0 > d1 ? d1 : d0;
|
||||
|
||||
tmp.diagonal().array () -= eivals(k);
|
||||
VectorType cross;
|
||||
Scalar n;
|
||||
n = (cross = tmp.row(0).cross(tmp.row(1))).squaredNorm();
|
||||
|
||||
if(n>safeNorm2)
|
||||
eivecs.col(k) = cross / sqrt(n);
|
||||
else
|
||||
Index k(0), l(2);
|
||||
if(d0 > d1)
|
||||
{
|
||||
n = (cross = tmp.row(0).cross(tmp.row(2))).squaredNorm();
|
||||
|
||||
if(n>safeNorm2)
|
||||
eivecs.col(k) = cross / sqrt(n);
|
||||
else
|
||||
{
|
||||
n = (cross = tmp.row(1).cross(tmp.row(2))).squaredNorm();
|
||||
|
||||
if(n>safeNorm2)
|
||||
eivecs.col(k) = cross / sqrt(n);
|
||||
else
|
||||
{
|
||||
// the input matrix and/or the eigenvaues probably contains some inf/NaN,
|
||||
// => exit
|
||||
// scale back to the original size.
|
||||
eivals *= scale;
|
||||
|
||||
solver.m_info = NumericalIssue;
|
||||
solver.m_isInitialized = true;
|
||||
solver.m_eigenvectorsOk = computeEigenvectors;
|
||||
return;
|
||||
}
|
||||
}
|
||||
std::swap(k,l);
|
||||
d0 = d1;
|
||||
}
|
||||
|
||||
tmp = scaledMat;
|
||||
tmp.diagonal().array() -= eivals(1);
|
||||
|
||||
if(d0<=Eigen::NumTraits<Scalar>::epsilon())
|
||||
eivecs.col(1) = eivecs.col(k).unitOrthogonal();
|
||||
else
|
||||
// Compute the eigenvector of index k
|
||||
{
|
||||
n = (cross = eivecs.col(k).cross(tmp.row(0).normalized())).squaredNorm();
|
||||
if(n>safeNorm2)
|
||||
eivecs.col(1) = cross / sqrt(n);
|
||||
else
|
||||
{
|
||||
n = (cross = eivecs.col(k).cross(tmp.row(1))).squaredNorm();
|
||||
if(n>safeNorm2)
|
||||
eivecs.col(1) = cross / sqrt(n);
|
||||
else
|
||||
{
|
||||
n = (cross = eivecs.col(k).cross(tmp.row(2))).squaredNorm();
|
||||
if(n>safeNorm2)
|
||||
eivecs.col(1) = cross / sqrt(n);
|
||||
else
|
||||
{
|
||||
// we should never reach this point,
|
||||
// if so the last two eigenvalues are likely to ve very closed to each other
|
||||
eivecs.col(1) = eivecs.col(k).unitOrthogonal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure that eivecs[1] is orthogonal to eivecs[2]
|
||||
Scalar d = eivecs.col(1).dot(eivecs.col(k));
|
||||
eivecs.col(1) = (eivecs.col(1) - d * eivecs.col(k)).normalized();
|
||||
tmp.diagonal().array () -= eivals(k);
|
||||
// By construction, 'tmp' is of rank 2, and its kernel corresponds to the respective eigenvector.
|
||||
extract_kernel(tmp, eivecs.col(k), eivecs.col(l));
|
||||
}
|
||||
|
||||
eivecs.col(k==2 ? 0 : 2) = eivecs.col(k).cross(eivecs.col(1)).normalized();
|
||||
// Compute eigenvector of index l
|
||||
if(d0<=2*Eigen::NumTraits<Scalar>::epsilon()*d1)
|
||||
{
|
||||
// If d0 is too small, then the two other eigenvalues are numerically the same,
|
||||
// and thus we only have to ortho-normalize the near orthogonal vector we saved above.
|
||||
eivecs.col(l) -= eivecs.col(k).dot(eivecs.col(l))*eivecs.col(l);
|
||||
eivecs.col(l).normalize();
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = scaledMat;
|
||||
tmp.diagonal().array () -= eivals(l);
|
||||
|
||||
VectorType dummy;
|
||||
extract_kernel(tmp, eivecs.col(l), dummy);
|
||||
}
|
||||
|
||||
// Compute last eigenvector from the other two
|
||||
eivecs.col(1) = eivecs.col(2).cross(eivecs.col(0)).normalized();
|
||||
}
|
||||
}
|
||||
|
||||
// Rescale back to the original size.
|
||||
eivals *= scale;
|
||||
eivals.array() += shift;
|
||||
|
||||
solver.m_info = Success;
|
||||
solver.m_isInitialized = true;
|
||||
|
|
@ -665,11 +655,12 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2
|
|||
typedef typename SolverType::MatrixType MatrixType;
|
||||
typedef typename SolverType::RealVectorType VectorType;
|
||||
typedef typename SolverType::Scalar Scalar;
|
||||
typedef typename SolverType::EigenvectorsType EigenvectorsType;
|
||||
|
||||
static inline void computeRoots(const MatrixType& m, VectorType& roots)
|
||||
{
|
||||
using std::sqrt;
|
||||
const Scalar t0 = Scalar(0.5) * sqrt( numext::abs2(m(0,0)-m(1,1)) + Scalar(4)*m(1,0)*m(1,0));
|
||||
const Scalar t0 = Scalar(0.5) * sqrt( numext::abs2(m(0,0)-m(1,1)) + Scalar(4)*numext::abs2(m(1,0)));
|
||||
const Scalar t1 = Scalar(0.5) * (m(0,0) + m(1,1));
|
||||
roots(0) = t1 - t0;
|
||||
roots(1) = t1 + t0;
|
||||
|
|
@ -678,13 +669,15 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2
|
|||
static inline void run(SolverType& solver, const MatrixType& mat, int options)
|
||||
{
|
||||
using std::sqrt;
|
||||
using std::abs;
|
||||
|
||||
eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows());
|
||||
eigen_assert((options&~(EigVecMask|GenEigMask))==0
|
||||
&& (options&EigVecMask)!=EigVecMask
|
||||
&& "invalid option parameter");
|
||||
bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
|
||||
|
||||
MatrixType& eivecs = solver.m_eivec;
|
||||
EigenvectorsType& eivecs = solver.m_eivec;
|
||||
VectorType& eivals = solver.m_eivalues;
|
||||
|
||||
// map the matrix coefficients to [-1:1] to avoid over- and underflow.
|
||||
|
|
@ -698,22 +691,29 @@ template<typename SolverType> struct direct_selfadjoint_eigenvalues<SolverType,2
|
|||
// compute the eigen vectors
|
||||
if(computeEigenvectors)
|
||||
{
|
||||
scaledMat.diagonal().array () -= eivals(1);
|
||||
Scalar a2 = numext::abs2(scaledMat(0,0));
|
||||
Scalar c2 = numext::abs2(scaledMat(1,1));
|
||||
Scalar b2 = numext::abs2(scaledMat(1,0));
|
||||
if(a2>c2)
|
||||
if((eivals(1)-eivals(0))<=abs(eivals(1))*Eigen::NumTraits<Scalar>::epsilon())
|
||||
{
|
||||
eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0);
|
||||
eivecs.col(1) /= sqrt(a2+b2);
|
||||
eivecs.setIdentity();
|
||||
}
|
||||
else
|
||||
{
|
||||
eivecs.col(1) << -scaledMat(1,1), scaledMat(1,0);
|
||||
eivecs.col(1) /= sqrt(c2+b2);
|
||||
}
|
||||
scaledMat.diagonal().array () -= eivals(1);
|
||||
Scalar a2 = numext::abs2(scaledMat(0,0));
|
||||
Scalar c2 = numext::abs2(scaledMat(1,1));
|
||||
Scalar b2 = numext::abs2(scaledMat(1,0));
|
||||
if(a2>c2)
|
||||
{
|
||||
eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0);
|
||||
eivecs.col(1) /= sqrt(a2+b2);
|
||||
}
|
||||
else
|
||||
{
|
||||
eivecs.col(1) << -scaledMat(1,1), scaledMat(1,0);
|
||||
eivecs.col(1) /= sqrt(c2+b2);
|
||||
}
|
||||
|
||||
eivecs.col(0) << eivecs.col(1).unitOrthogonal();
|
||||
eivecs.col(0) << eivecs.col(1).unitOrthogonal();
|
||||
}
|
||||
}
|
||||
|
||||
// Rescale back to the original size.
|
||||
|
|
@ -736,7 +736,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
|
|||
}
|
||||
|
||||
namespace internal {
|
||||
template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
|
||||
template<typename RealScalar, typename Scalar, typename Index>
|
||||
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n)
|
||||
{
|
||||
using std::abs;
|
||||
|
|
@ -788,8 +788,7 @@ static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index sta
|
|||
// apply the givens rotation to the unit matrix Q = Q * G
|
||||
if (matrixQ)
|
||||
{
|
||||
// FIXME if StorageOrder == RowMajor this operation is not very efficient
|
||||
Map<Matrix<Scalar,Dynamic,Dynamic,StorageOrder> > q(matrixQ,n,n);
|
||||
Map<Matrix<Scalar,Dynamic,Dynamic,ColMajor> > q(matrixQ,n,n);
|
||||
q.applyOnTheRight(k,k+1,rot);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@ namespace Eigen {
|
|||
*
|
||||
* \brief An axis aligned box
|
||||
*
|
||||
* \param _Scalar the type of the scalar coefficients
|
||||
* \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic.
|
||||
* \tparam _Scalar the type of the scalar coefficients
|
||||
* \tparam _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic.
|
||||
*
|
||||
* This class represents an axis aligned box as a pair of the minimal and maximal corners.
|
||||
* \warning The result of most methods is undefined when applied to an empty box. You can check for empty boxes using isEmpty().
|
||||
* \sa alignedboxtypedefs
|
||||
*/
|
||||
template <typename _Scalar, int _AmbientDim>
|
||||
class AlignedBox
|
||||
|
|
@ -40,18 +42,21 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||
/** Define constants to name the corners of a 1D, 2D or 3D axis aligned bounding box */
|
||||
enum CornerType
|
||||
{
|
||||
/** 1D names */
|
||||
/** 1D names @{ */
|
||||
Min=0, Max=1,
|
||||
/** @} */
|
||||
|
||||
/** Added names for 2D */
|
||||
/** Identifier for 2D corner @{ */
|
||||
BottomLeft=0, BottomRight=1,
|
||||
TopLeft=2, TopRight=3,
|
||||
/** @} */
|
||||
|
||||
/** Added names for 3D */
|
||||
/** Identifier for 3D corner @{ */
|
||||
BottomLeftFloor=0, BottomRightFloor=1,
|
||||
TopLeftFloor=2, TopRightFloor=3,
|
||||
BottomLeftCeil=4, BottomRightCeil=5,
|
||||
TopLeftCeil=6, TopRightCeil=7
|
||||
/** @} */
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -63,34 +68,33 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||
inline explicit AlignedBox(Index _dim) : m_min(_dim), m_max(_dim)
|
||||
{ setEmpty(); }
|
||||
|
||||
/** Constructs a box with extremities \a _min and \a _max. */
|
||||
/** Constructs a box with extremities \a _min and \a _max.
|
||||
* \warning If either component of \a _min is larger than the same component of \a _max, the constructed box is empty. */
|
||||
template<typename OtherVectorType1, typename OtherVectorType2>
|
||||
inline AlignedBox(const OtherVectorType1& _min, const OtherVectorType2& _max) : m_min(_min), m_max(_max) {}
|
||||
|
||||
/** Constructs a box containing a single point \a p. */
|
||||
template<typename Derived>
|
||||
inline explicit AlignedBox(const MatrixBase<Derived>& a_p)
|
||||
{
|
||||
typename internal::nested<Derived,2>::type p(a_p.derived());
|
||||
m_min = p;
|
||||
m_max = p;
|
||||
}
|
||||
inline explicit AlignedBox(const MatrixBase<Derived>& p) : m_min(p), m_max(m_min)
|
||||
{ }
|
||||
|
||||
~AlignedBox() {}
|
||||
|
||||
/** \returns the dimension in which the box holds */
|
||||
inline Index dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size() : Index(AmbientDimAtCompileTime); }
|
||||
|
||||
/** \deprecated use isEmpty */
|
||||
/** \deprecated use isEmpty() */
|
||||
inline bool isNull() const { return isEmpty(); }
|
||||
|
||||
/** \deprecated use setEmpty */
|
||||
/** \deprecated use setEmpty() */
|
||||
inline void setNull() { setEmpty(); }
|
||||
|
||||
/** \returns true if the box is empty. */
|
||||
/** \returns true if the box is empty.
|
||||
* \sa setEmpty */
|
||||
inline bool isEmpty() const { return (m_min.array() > m_max.array()).any(); }
|
||||
|
||||
/** Makes \c *this an empty box. */
|
||||
/** Makes \c *this an empty box.
|
||||
* \sa isEmpty */
|
||||
inline void setEmpty()
|
||||
{
|
||||
m_min.setConstant( ScalarTraits::highest() );
|
||||
|
|
@ -159,7 +163,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||
* a uniform distribution */
|
||||
inline VectorType sample() const
|
||||
{
|
||||
VectorType r;
|
||||
VectorType r(dim());
|
||||
for(Index d=0; d<dim(); ++d)
|
||||
{
|
||||
if(!ScalarTraits::IsInteger)
|
||||
|
|
@ -175,27 +179,34 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||
|
||||
/** \returns true if the point \a p is inside the box \c *this. */
|
||||
template<typename Derived>
|
||||
inline bool contains(const MatrixBase<Derived>& a_p) const
|
||||
inline bool contains(const MatrixBase<Derived>& p) const
|
||||
{
|
||||
typename internal::nested<Derived,2>::type p(a_p.derived());
|
||||
return (m_min.array()<=p.array()).all() && (p.array()<=m_max.array()).all();
|
||||
typename internal::nested<Derived,2>::type p_n(p.derived());
|
||||
return (m_min.array()<=p_n.array()).all() && (p_n.array()<=m_max.array()).all();
|
||||
}
|
||||
|
||||
/** \returns true if the box \a b is entirely inside the box \c *this. */
|
||||
inline bool contains(const AlignedBox& b) const
|
||||
{ return (m_min.array()<=(b.min)().array()).all() && ((b.max)().array()<=m_max.array()).all(); }
|
||||
|
||||
/** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */
|
||||
/** \returns true if the box \a b is intersecting the box \c *this.
|
||||
* \sa intersection, clamp */
|
||||
inline bool intersects(const AlignedBox& b) const
|
||||
{ return (m_min.array()<=(b.max)().array()).all() && ((b.min)().array()<=m_max.array()).all(); }
|
||||
|
||||
/** Extends \c *this such that it contains the point \a p and returns a reference to \c *this.
|
||||
* \sa extend(const AlignedBox&) */
|
||||
template<typename Derived>
|
||||
inline AlignedBox& extend(const MatrixBase<Derived>& a_p)
|
||||
inline AlignedBox& extend(const MatrixBase<Derived>& p)
|
||||
{
|
||||
typename internal::nested<Derived,2>::type p(a_p.derived());
|
||||
m_min = m_min.cwiseMin(p);
|
||||
m_max = m_max.cwiseMax(p);
|
||||
typename internal::nested<Derived,2>::type p_n(p.derived());
|
||||
m_min = m_min.cwiseMin(p_n);
|
||||
m_max = m_max.cwiseMax(p_n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. */
|
||||
/** Extends \c *this such that it contains the box \a b and returns a reference to \c *this.
|
||||
* \sa merged, extend(const MatrixBase&) */
|
||||
inline AlignedBox& extend(const AlignedBox& b)
|
||||
{
|
||||
m_min = m_min.cwiseMin(b.m_min);
|
||||
|
|
@ -203,7 +214,9 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||
return *this;
|
||||
}
|
||||
|
||||
/** Clamps \c *this by the box \a b and returns a reference to \c *this. */
|
||||
/** Clamps \c *this by the box \a b and returns a reference to \c *this.
|
||||
* \note If the boxes don't intersect, the resulting box is empty.
|
||||
* \sa intersection(), intersects() */
|
||||
inline AlignedBox& clamp(const AlignedBox& b)
|
||||
{
|
||||
m_min = m_min.cwiseMax(b.m_min);
|
||||
|
|
@ -211,11 +224,15 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||
return *this;
|
||||
}
|
||||
|
||||
/** Returns an AlignedBox that is the intersection of \a b and \c *this */
|
||||
/** Returns an AlignedBox that is the intersection of \a b and \c *this
|
||||
* \note If the boxes don't intersect, the resulting box is empty.
|
||||
* \sa intersects(), clamp, contains() */
|
||||
inline AlignedBox intersection(const AlignedBox& b) const
|
||||
{return AlignedBox(m_min.cwiseMax(b.m_min), m_max.cwiseMin(b.m_max)); }
|
||||
|
||||
/** Returns an AlignedBox that is the union of \a b and \c *this */
|
||||
/** Returns an AlignedBox that is the union of \a b and \c *this.
|
||||
* \note Merging with an empty box may result in a box bigger than \c *this.
|
||||
* \sa extend(const AlignedBox&) */
|
||||
inline AlignedBox merged(const AlignedBox& b) const
|
||||
{ return AlignedBox(m_min.cwiseMin(b.m_min), m_max.cwiseMax(b.m_max)); }
|
||||
|
||||
|
|
@ -231,20 +248,20 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||
|
||||
/** \returns the squared distance between the point \a p and the box \c *this,
|
||||
* and zero if \a p is inside the box.
|
||||
* \sa exteriorDistance()
|
||||
* \sa exteriorDistance(const MatrixBase&), squaredExteriorDistance(const AlignedBox&)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline Scalar squaredExteriorDistance(const MatrixBase<Derived>& a_p) const;
|
||||
inline Scalar squaredExteriorDistance(const MatrixBase<Derived>& p) const;
|
||||
|
||||
/** \returns the squared distance between the boxes \a b and \c *this,
|
||||
* and zero if the boxes intersect.
|
||||
* \sa exteriorDistance()
|
||||
* \sa exteriorDistance(const AlignedBox&), squaredExteriorDistance(const MatrixBase&)
|
||||
*/
|
||||
inline Scalar squaredExteriorDistance(const AlignedBox& b) const;
|
||||
|
||||
/** \returns the distance between the point \a p and the box \c *this,
|
||||
* and zero if \a p is inside the box.
|
||||
* \sa squaredExteriorDistance()
|
||||
* \sa squaredExteriorDistance(const MatrixBase&), exteriorDistance(const AlignedBox&)
|
||||
*/
|
||||
template<typename Derived>
|
||||
inline NonInteger exteriorDistance(const MatrixBase<Derived>& p) const
|
||||
|
|
@ -252,7 +269,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
|
|||
|
||||
/** \returns the distance between the boxes \a b and \c *this,
|
||||
* and zero if the boxes intersect.
|
||||
* \sa squaredExteriorDistance()
|
||||
* \sa squaredExteriorDistance(const AlignedBox&), exteriorDistance(const MatrixBase&)
|
||||
*/
|
||||
inline NonInteger exteriorDistance(const AlignedBox& b) const
|
||||
{ using std::sqrt; return sqrt(NonInteger(squaredExteriorDistance(b))); }
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ template<typename MatrixType,int _Direction> class Homogeneous
|
|||
{
|
||||
if( (int(Direction)==Vertical && row==m_matrix.rows())
|
||||
|| (int(Direction)==Horizontal && col==m_matrix.cols()))
|
||||
return 1;
|
||||
return Scalar(1);
|
||||
return m_matrix.coeff(row, col);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,7 +100,17 @@ public:
|
|||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 3)
|
||||
Hyperplane result(p0.size());
|
||||
result.normal() = (p2 - p0).cross(p1 - p0).normalized();
|
||||
VectorType v0(p2 - p0), v1(p1 - p0);
|
||||
result.normal() = v0.cross(v1);
|
||||
RealScalar norm = result.normal().norm();
|
||||
if(norm <= v0.norm() * v1.norm() * NumTraits<RealScalar>::epsilon())
|
||||
{
|
||||
Matrix<Scalar,2,3> m; m << v0.transpose(), v1.transpose();
|
||||
JacobiSVD<Matrix<Scalar,2,3> > svd(m, ComputeFullV);
|
||||
result.normal() = svd.matrixV().col(2);
|
||||
}
|
||||
else
|
||||
result.normal() /= norm;
|
||||
result.offset() = -p0.dot(result.normal());
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,11 +102,11 @@ public:
|
|||
/** \returns a quaternion representing an identity rotation
|
||||
* \sa MatrixBase::Identity()
|
||||
*/
|
||||
static inline Quaternion<Scalar> Identity() { return Quaternion<Scalar>(1, 0, 0, 0); }
|
||||
static inline Quaternion<Scalar> Identity() { return Quaternion<Scalar>(Scalar(1), Scalar(0), Scalar(0), Scalar(0)); }
|
||||
|
||||
/** \sa QuaternionBase::Identity(), MatrixBase::setIdentity()
|
||||
*/
|
||||
inline QuaternionBase& setIdentity() { coeffs() << 0, 0, 0, 1; return *this; }
|
||||
inline QuaternionBase& setIdentity() { coeffs() << Scalar(0), Scalar(0), Scalar(0), Scalar(1); return *this; }
|
||||
|
||||
/** \returns the squared norm of the quaternion's coefficients
|
||||
* \sa QuaternionBase::norm(), MatrixBase::squaredNorm()
|
||||
|
|
@ -161,7 +161,7 @@ public:
|
|||
{ return coeffs().isApprox(other.coeffs(), prec); }
|
||||
|
||||
/** return the result vector of \a v through the rotation*/
|
||||
EIGEN_STRONG_INLINE Vector3 _transformVector(Vector3 v) const;
|
||||
EIGEN_STRONG_INLINE Vector3 _transformVector(const Vector3& v) const;
|
||||
|
||||
/** \returns \c *this with scalar type casted to \a NewScalarType
|
||||
*
|
||||
|
|
@ -231,7 +231,7 @@ class Quaternion : public QuaternionBase<Quaternion<_Scalar,_Options> >
|
|||
public:
|
||||
typedef _Scalar Scalar;
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Quaternion)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Quaternion)
|
||||
using Base::operator*=;
|
||||
|
||||
typedef typename internal::traits<Quaternion>::Coefficients Coefficients;
|
||||
|
|
@ -341,7 +341,7 @@ class Map<const Quaternion<_Scalar>, _Options >
|
|||
public:
|
||||
typedef _Scalar Scalar;
|
||||
typedef typename internal::traits<Map>::Coefficients Coefficients;
|
||||
EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Map)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
|
||||
using Base::operator*=;
|
||||
|
||||
/** Constructs a Mapped Quaternion object from the pointer \a coeffs
|
||||
|
|
@ -378,7 +378,7 @@ class Map<Quaternion<_Scalar>, _Options >
|
|||
public:
|
||||
typedef _Scalar Scalar;
|
||||
typedef typename internal::traits<Map>::Coefficients Coefficients;
|
||||
EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Map)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
|
||||
using Base::operator*=;
|
||||
|
||||
/** Constructs a Mapped Quaternion object from the pointer \a coeffs
|
||||
|
|
@ -461,7 +461,7 @@ EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator*= (const Quaterni
|
|||
*/
|
||||
template <class Derived>
|
||||
EIGEN_STRONG_INLINE typename QuaternionBase<Derived>::Vector3
|
||||
QuaternionBase<Derived>::_transformVector(Vector3 v) const
|
||||
QuaternionBase<Derived>::_transformVector(const Vector3& v) const
|
||||
{
|
||||
// Note that this algorithm comes from the optimization by hand
|
||||
// of the conversion to a Matrix followed by a Matrix/Vector product.
|
||||
|
|
@ -637,7 +637,7 @@ inline Quaternion<typename internal::traits<Derived>::Scalar> QuaternionBase<Der
|
|||
{
|
||||
// FIXME should this function be called multiplicativeInverse and conjugate() be called inverse() or opposite() ??
|
||||
Scalar n2 = this->squaredNorm();
|
||||
if (n2 > 0)
|
||||
if (n2 > Scalar(0))
|
||||
return Quaternion<Scalar>(conjugate().coeffs() / n2);
|
||||
else
|
||||
{
|
||||
|
|
@ -667,12 +667,10 @@ template <class OtherDerived>
|
|||
inline typename internal::traits<Derived>::Scalar
|
||||
QuaternionBase<Derived>::angularDistance(const QuaternionBase<OtherDerived>& other) const
|
||||
{
|
||||
using std::acos;
|
||||
using std::atan2;
|
||||
using std::abs;
|
||||
Scalar d = abs(this->dot(other));
|
||||
if (d>=Scalar(1))
|
||||
return Scalar(0);
|
||||
return Scalar(2) * acos(d);
|
||||
Quaternion<Scalar> d = (*this) * other.conjugate();
|
||||
return Scalar(2) * atan2( d.vec().norm(), abs(d.w()) );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -712,7 +710,7 @@ QuaternionBase<Derived>::slerp(const Scalar& t, const QuaternionBase<OtherDerive
|
|||
scale0 = sin( ( Scalar(1) - t ) * theta) / sinTheta;
|
||||
scale1 = sin( ( t * theta) ) / sinTheta;
|
||||
}
|
||||
if(d<0) scale1 = -scale1;
|
||||
if(d<Scalar(0)) scale1 = -scale1;
|
||||
|
||||
return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ public:
|
|||
|
||||
/** Construct a 2D counter clock wise rotation from the angle \a a in radian. */
|
||||
inline Rotation2D(const Scalar& a) : m_angle(a) {}
|
||||
|
||||
/** Default constructor wihtout initialization. The represented rotation is undefined. */
|
||||
Rotation2D() {}
|
||||
|
||||
/** \returns the rotation angle */
|
||||
inline Scalar angle() const { return m_angle; }
|
||||
|
|
@ -81,10 +84,10 @@ public:
|
|||
/** Applies the rotation to a 2D vector */
|
||||
Vector2 operator* (const Vector2& vec) const
|
||||
{ return toRotationMatrix() * vec; }
|
||||
|
||||
|
||||
template<typename Derived>
|
||||
Rotation2D& fromRotationMatrix(const MatrixBase<Derived>& m);
|
||||
Matrix2 toRotationMatrix(void) const;
|
||||
Matrix2 toRotationMatrix() const;
|
||||
|
||||
/** \returns the spherical interpolation between \c *this and \a other using
|
||||
* parameter \a t. It is in fact equivalent to a linear interpolation.
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ struct transform_construct_from_matrix;
|
|||
|
||||
template<typename TransformType> struct transform_take_affine_part;
|
||||
|
||||
template<int Mode> struct transform_make_affine;
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** \geometry_module \ingroup Geometry_Module
|
||||
|
|
@ -230,8 +232,7 @@ public:
|
|||
inline Transform()
|
||||
{
|
||||
check_template_params();
|
||||
if (int(Mode)==Affine)
|
||||
makeAffine();
|
||||
internal::transform_make_affine<(int(Mode)==Affine) ? Affine : AffineCompact>::run(m_matrix);
|
||||
}
|
||||
|
||||
inline Transform(const Transform& other)
|
||||
|
|
@ -591,11 +592,7 @@ public:
|
|||
*/
|
||||
void makeAffine()
|
||||
{
|
||||
if(int(Mode)!=int(AffineCompact))
|
||||
{
|
||||
matrix().template block<1,Dim>(Dim,0).setZero();
|
||||
matrix().coeffRef(Dim,Dim) = Scalar(1);
|
||||
}
|
||||
internal::transform_make_affine<int(Mode)>::run(m_matrix);
|
||||
}
|
||||
|
||||
/** \internal
|
||||
|
|
@ -1079,6 +1076,24 @@ Transform<Scalar,Dim,Mode,Options>::fromPositionOrientationScale(const MatrixBas
|
|||
|
||||
namespace internal {
|
||||
|
||||
template<int Mode>
|
||||
struct transform_make_affine
|
||||
{
|
||||
template<typename MatrixType>
|
||||
static void run(MatrixType &mat)
|
||||
{
|
||||
static const int Dim = MatrixType::ColsAtCompileTime-1;
|
||||
mat.template block<1,Dim>(Dim,0).setZero();
|
||||
mat.coeffRef(Dim,Dim) = typename MatrixType::Scalar(1);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct transform_make_affine<AffineCompact>
|
||||
{
|
||||
template<typename MatrixType> static void run(MatrixType &) { }
|
||||
};
|
||||
|
||||
// selector needed to avoid taking the inverse of a 3x4 matrix
|
||||
template<typename TransformType, int Mode=TransformType::Mode>
|
||||
struct projective_transform_inverse
|
||||
|
|
|
|||
|
|
@ -65,10 +65,10 @@ class DiagonalPreconditioner
|
|||
{
|
||||
typename MatType::InnerIterator it(mat,j);
|
||||
while(it && it.index()!=j) ++it;
|
||||
if(it && it.index()==j)
|
||||
if(it && it.index()==j && it.value()!=Scalar(0))
|
||||
m_invdiag(j) = Scalar(1)/it.value();
|
||||
else
|
||||
m_invdiag(j) = 0;
|
||||
m_invdiag(j) = Scalar(1);
|
||||
}
|
||||
m_isInitialized = true;
|
||||
return *this;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ bool bicgstab(const MatrixType& mat, const Rhs& rhs, Dest& x,
|
|||
int maxIters = iters;
|
||||
|
||||
int n = mat.cols();
|
||||
x = precond.solve(x);
|
||||
VectorType r = rhs - mat * x;
|
||||
VectorType r0 = r;
|
||||
|
||||
|
|
@ -143,7 +142,7 @@ struct traits<BiCGSTAB<_MatrixType,_Preconditioner> >
|
|||
* SparseMatrix<double> A(n,n);
|
||||
* // fill A and b
|
||||
* BiCGSTAB<SparseMatrix<double> > solver;
|
||||
* solver(A);
|
||||
* solver.compute(A);
|
||||
* x = solver.solve(b);
|
||||
* std::cout << "#iterations: " << solver.iterations() << std::endl;
|
||||
* std::cout << "estimated error: " << solver.error() << std::endl;
|
||||
|
|
@ -152,20 +151,7 @@ struct traits<BiCGSTAB<_MatrixType,_Preconditioner> >
|
|||
* \endcode
|
||||
*
|
||||
* By default the iterations start with x=0 as an initial guess of the solution.
|
||||
* One can control the start using the solveWithGuess() method. Here is a step by
|
||||
* step execution example starting with a random guess and printing the evolution
|
||||
* of the estimated error:
|
||||
* * \code
|
||||
* x = VectorXd::Random(n);
|
||||
* solver.setMaxIterations(1);
|
||||
* int i = 0;
|
||||
* do {
|
||||
* x = solver.solveWithGuess(b,x);
|
||||
* std::cout << i << " : " << solver.error() << std::endl;
|
||||
* ++i;
|
||||
* } while (solver.info()!=Success && i<100);
|
||||
* \endcode
|
||||
* Note that such a step by step excution is slightly slower.
|
||||
* One can control the start using the solveWithGuess() method.
|
||||
*
|
||||
* \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -112,9 +112,9 @@ struct traits<ConjugateGradient<_MatrixType,_UpLo,_Preconditioner> >
|
|||
* This class allows to solve for A.x = b sparse linear problems using a conjugate gradient algorithm.
|
||||
* The sparse matrix A must be selfadjoint. The vectors x and b can be either dense or sparse.
|
||||
*
|
||||
* \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix.
|
||||
* \tparam _UpLo the triangular part that will be used for the computations. It can be Lower
|
||||
* or Upper. Default is Lower.
|
||||
* \tparam _MatrixType the type of the matrix A, can be a dense or a sparse matrix.
|
||||
* \tparam _UpLo the triangular part that will be used for the computations. It can be Lower,
|
||||
* Upper, or Lower|Upper in which the full matrix entries will be considered. Default is Lower.
|
||||
* \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner
|
||||
*
|
||||
* The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()
|
||||
|
|
@ -137,20 +137,7 @@ struct traits<ConjugateGradient<_MatrixType,_UpLo,_Preconditioner> >
|
|||
* \endcode
|
||||
*
|
||||
* By default the iterations start with x=0 as an initial guess of the solution.
|
||||
* One can control the start using the solveWithGuess() method. Here is a step by
|
||||
* step execution example starting with a random guess and printing the evolution
|
||||
* of the estimated error:
|
||||
* * \code
|
||||
* x = VectorXd::Random(n);
|
||||
* cg.setMaxIterations(1);
|
||||
* int i = 0;
|
||||
* do {
|
||||
* x = cg.solveWithGuess(b,x);
|
||||
* std::cout << i << " : " << cg.error() << std::endl;
|
||||
* ++i;
|
||||
* } while (cg.info()!=Success && i<100);
|
||||
* \endcode
|
||||
* Note that such a step by step excution is slightly slower.
|
||||
* One can control the start using the solveWithGuess() method.
|
||||
*
|
||||
* \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner
|
||||
*/
|
||||
|
|
@ -213,6 +200,10 @@ public:
|
|||
template<typename Rhs,typename Dest>
|
||||
void _solveWithGuess(const Rhs& b, Dest& x) const
|
||||
{
|
||||
typedef typename internal::conditional<UpLo==(Lower|Upper),
|
||||
const MatrixType&,
|
||||
SparseSelfAdjointView<const MatrixType, UpLo>
|
||||
>::type MatrixWrapperType;
|
||||
m_iterations = Base::maxIterations();
|
||||
m_error = Base::m_tolerance;
|
||||
|
||||
|
|
@ -222,8 +213,7 @@ public:
|
|||
m_error = Base::m_tolerance;
|
||||
|
||||
typename Dest::ColXpr xj(x,j);
|
||||
internal::conjugate_gradient(mp_matrix->template selfadjointView<UpLo>(), b.col(j), xj,
|
||||
Base::m_preconditioner, m_iterations, m_error);
|
||||
internal::conjugate_gradient(MatrixWrapperType(*mp_matrix), b.col(j), xj, Base::m_preconditioner, m_iterations, m_error);
|
||||
}
|
||||
|
||||
m_isInitialized = true;
|
||||
|
|
@ -234,7 +224,7 @@ public:
|
|||
template<typename Rhs,typename Dest>
|
||||
void _solve(const Rhs& b, Dest& x) const
|
||||
{
|
||||
x.setOnes();
|
||||
x.setZero();
|
||||
_solveWithGuess(b,x);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -150,7 +150,6 @@ class IncompleteLUT : internal::noncopyable
|
|||
{
|
||||
analyzePattern(amat);
|
||||
factorize(amat);
|
||||
m_isInitialized = m_factorizationIsOk;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -235,6 +234,8 @@ void IncompleteLUT<Scalar>::analyzePattern(const _MatrixType& amat)
|
|||
m_Pinv = m_P.inverse(); // ... and the inverse permutation
|
||||
|
||||
m_analysisIsOk = true;
|
||||
m_factorizationIsOk = false;
|
||||
m_isInitialized = false;
|
||||
}
|
||||
|
||||
template <typename Scalar>
|
||||
|
|
@ -442,6 +443,7 @@ void IncompleteLUT<Scalar>::factorize(const _MatrixType& amat)
|
|||
m_lu.makeCompressed();
|
||||
|
||||
m_factorizationIsOk = true;
|
||||
m_isInitialized = m_factorizationIsOk;
|
||||
m_info = Success;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -374,6 +374,12 @@ template<typename _MatrixType> class FullPivLU
|
|||
inline Index cols() const { return m_lu.cols(); }
|
||||
|
||||
protected:
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
MatrixType m_lu;
|
||||
PermutationPType m_p;
|
||||
PermutationQType m_q;
|
||||
|
|
@ -418,6 +424,8 @@ FullPivLU<MatrixType>::FullPivLU(const MatrixType& matrix)
|
|||
template<typename MatrixType>
|
||||
FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
// the permutations are stored as int indices, so just to be sure:
|
||||
eigen_assert(matrix.rows()<=NumTraits<int>::highest() && matrix.cols()<=NumTraits<int>::highest());
|
||||
|
||||
|
|
|
|||
|
|
@ -171,6 +171,12 @@ template<typename _MatrixType> class PartialPivLU
|
|||
inline Index cols() const { return m_lu.cols(); }
|
||||
|
||||
protected:
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
MatrixType m_lu;
|
||||
PermutationType m_p;
|
||||
TranspositionType m_rowsTranspositions;
|
||||
|
|
@ -386,6 +392,8 @@ void partial_lu_inplace(MatrixType& lu, TranspositionType& row_transpositions, t
|
|||
template<typename MatrixType>
|
||||
PartialPivLU<MatrixType>& PartialPivLU<MatrixType>::compute(const MatrixType& matrix)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
// the row permutation is stored as int indices, so just to be sure:
|
||||
eigen_assert(matrix.rows()<NumTraits<int>::highest());
|
||||
|
||||
|
|
|
|||
|
|
@ -137,22 +137,27 @@ void minimum_degree_ordering(SparseMatrix<Scalar,ColMajor,Index>& C, Permutation
|
|||
degree[i] = len[i]; // degree of node i
|
||||
}
|
||||
mark = internal::cs_wclear<Index>(0, 0, w, n); /* clear w */
|
||||
elen[n] = -2; /* n is a dead element */
|
||||
Cp[n] = -1; /* n is a root of assembly tree */
|
||||
w[n] = 0; /* n is a dead element */
|
||||
|
||||
/* --- Initialize degree lists ------------------------------------------ */
|
||||
for(i = 0; i < n; i++)
|
||||
{
|
||||
bool has_diag = false;
|
||||
for(p = Cp[i]; p<Cp[i+1]; ++p)
|
||||
if(Ci[p]==i)
|
||||
{
|
||||
has_diag = true;
|
||||
break;
|
||||
}
|
||||
|
||||
d = degree[i];
|
||||
if(d == 0) /* node i is empty */
|
||||
if(d == 1 && has_diag) /* node i is empty */
|
||||
{
|
||||
elen[i] = -2; /* element i is dead */
|
||||
nel++;
|
||||
Cp[i] = -1; /* i is a root of assembly tree */
|
||||
w[i] = 0;
|
||||
}
|
||||
else if(d > dense) /* node i is dense */
|
||||
else if(d > dense || !has_diag) /* node i is dense or has no structural diagonal element */
|
||||
{
|
||||
nv[i] = 0; /* absorb i into element n */
|
||||
elen[i] = -1; /* node i is dead */
|
||||
|
|
@ -168,6 +173,10 @@ void minimum_degree_ordering(SparseMatrix<Scalar,ColMajor,Index>& C, Permutation
|
|||
}
|
||||
}
|
||||
|
||||
elen[n] = -2; /* n is a dead element */
|
||||
Cp[n] = -1; /* n is a root of assembly tree */
|
||||
w[n] = 0; /* n is a dead element */
|
||||
|
||||
while (nel < n) /* while (selecting pivots) do */
|
||||
{
|
||||
/* --- Select node of minimum approximate degree -------------------- */
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ class PardisoImpl
|
|||
void pardisoInit(int type)
|
||||
{
|
||||
m_type = type;
|
||||
bool symmetric = abs(m_type) < 10;
|
||||
bool symmetric = std::abs(m_type) < 10;
|
||||
m_iparm[0] = 1; // No solver default
|
||||
m_iparm[1] = 3; // use Metis for the ordering
|
||||
m_iparm[2] = 1; // Numbers of processors, value of OMP_NUM_THREADS
|
||||
|
|
|
|||
|
|
@ -384,6 +384,12 @@ template<typename _MatrixType> class ColPivHouseholderQR
|
|||
}
|
||||
|
||||
protected:
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
MatrixType m_qr;
|
||||
HCoeffsType m_hCoeffs;
|
||||
PermutationType m_colsPermutation;
|
||||
|
|
@ -422,6 +428,8 @@ typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::logAbsDetermina
|
|||
template<typename MatrixType>
|
||||
ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
using std::abs;
|
||||
Index rows = matrix.rows();
|
||||
Index cols = matrix.cols();
|
||||
|
|
@ -463,20 +471,10 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
|
|||
// we store that back into our table: it can't hurt to correct our table.
|
||||
m_colSqNorms.coeffRef(biggest_col_index) = biggest_col_sq_norm;
|
||||
|
||||
// if the current biggest column is smaller than epsilon times the initial biggest column,
|
||||
// terminate to avoid generating nan/inf values.
|
||||
// Note that here, if we test instead for "biggest == 0", we get a failure every 1000 (or so)
|
||||
// repetitions of the unit test, with the result of solve() filled with large values of the order
|
||||
// of 1/(size*epsilon).
|
||||
if(biggest_col_sq_norm < threshold_helper * RealScalar(rows-k))
|
||||
{
|
||||
// Track the number of meaningful pivots but do not stop the decomposition to make
|
||||
// sure that the initial matrix is properly reproduced. See bug 941.
|
||||
if(m_nonzero_pivots==size && biggest_col_sq_norm < threshold_helper * RealScalar(rows-k))
|
||||
m_nonzero_pivots = k;
|
||||
m_hCoeffs.tail(size-k).setZero();
|
||||
m_qr.bottomRightCorner(rows-k,cols-k)
|
||||
.template triangularView<StrictlyLower>()
|
||||
.setZero();
|
||||
break;
|
||||
}
|
||||
|
||||
// apply the transposition to the columns
|
||||
m_colsTranspositions.coeffRef(k) = biggest_col_index;
|
||||
|
|
@ -505,7 +503,7 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
|
|||
}
|
||||
|
||||
m_colsPermutation.setIdentity(PermIndexType(cols));
|
||||
for(PermIndexType k = 0; k < m_nonzero_pivots; ++k)
|
||||
for(PermIndexType k = 0; k < size/*m_nonzero_pivots*/; ++k)
|
||||
m_colsPermutation.applyTranspositionOnTheRight(k, PermIndexType(m_colsTranspositions.coeff(k)));
|
||||
|
||||
m_det_pq = (number_of_transpositions%2) ? -1 : 1;
|
||||
|
|
@ -555,13 +553,15 @@ struct solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
|
|||
|
||||
} // end namespace internal
|
||||
|
||||
/** \returns the matrix Q as a sequence of householder transformations */
|
||||
/** \returns the matrix Q as a sequence of householder transformations.
|
||||
* You can extract the meaningful part only by using:
|
||||
* \code qr.householderQ().setLength(qr.nonzeroPivots()) \endcode*/
|
||||
template<typename MatrixType>
|
||||
typename ColPivHouseholderQR<MatrixType>::HouseholderSequenceType ColPivHouseholderQR<MatrixType>
|
||||
::householderQ() const
|
||||
{
|
||||
eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
|
||||
return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate()).setLength(m_nonzero_pivots);
|
||||
return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
|
||||
}
|
||||
|
||||
/** \return the column-pivoting Householder QR decomposition of \c *this.
|
||||
|
|
|
|||
|
|
@ -63,12 +63,12 @@ ColPivHouseholderQR<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynami
|
|||
\
|
||||
m_nonzero_pivots = 0; \
|
||||
m_maxpivot = RealScalar(0);\
|
||||
m_colsPermutation.resize((int)cols); \
|
||||
m_colsPermutation.resize(cols); \
|
||||
m_colsPermutation.indices().setZero(); \
|
||||
\
|
||||
lapack_int lda = (lapack_int) m_qr.outerStride(), i; \
|
||||
lapack_int lda = m_qr.outerStride(), i; \
|
||||
lapack_int matrix_order = MKLCOLROW; \
|
||||
LAPACKE_##MKLPREFIX##geqp3( matrix_order, (lapack_int)rows, (lapack_int)cols, (MKLTYPE*)m_qr.data(), lda, (lapack_int*)m_colsPermutation.indices().data(), (MKLTYPE*)m_hCoeffs.data()); \
|
||||
LAPACKE_##MKLPREFIX##geqp3( matrix_order, rows, cols, (MKLTYPE*)m_qr.data(), lda, (lapack_int*)m_colsPermutation.indices().data(), (MKLTYPE*)m_hCoeffs.data()); \
|
||||
m_isInitialized = true; \
|
||||
m_maxpivot=m_qr.diagonal().cwiseAbs().maxCoeff(); \
|
||||
m_hCoeffs.adjointInPlace(); \
|
||||
|
|
|
|||
|
|
@ -368,6 +368,12 @@ template<typename _MatrixType> class FullPivHouseholderQR
|
|||
RealScalar maxPivot() const { return m_maxpivot; }
|
||||
|
||||
protected:
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
MatrixType m_qr;
|
||||
HCoeffsType m_hCoeffs;
|
||||
IntDiagSizeVectorType m_rows_transpositions;
|
||||
|
|
@ -407,6 +413,8 @@ typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::logAbsDetermin
|
|||
template<typename MatrixType>
|
||||
FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
using std::abs;
|
||||
Index rows = matrix.rows();
|
||||
Index cols = matrix.cols();
|
||||
|
|
|
|||
|
|
@ -189,6 +189,12 @@ template<typename _MatrixType> class HouseholderQR
|
|||
const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
|
||||
|
||||
protected:
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
MatrixType m_qr;
|
||||
HCoeffsType m_hCoeffs;
|
||||
RowVectorType m_temp;
|
||||
|
|
@ -349,6 +355,8 @@ struct solve_retval<HouseholderQR<_MatrixType>, Rhs>
|
|||
template<typename MatrixType>
|
||||
HouseholderQR<MatrixType>& HouseholderQR<MatrixType>::compute(const MatrixType& matrix)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
Index rows = matrix.rows();
|
||||
Index cols = matrix.cols();
|
||||
Index size = (std::min)(rows,cols);
|
||||
|
|
|
|||
|
|
@ -64,19 +64,13 @@ class SPQR
|
|||
typedef PermutationMatrix<Dynamic, Dynamic> PermutationType;
|
||||
public:
|
||||
SPQR()
|
||||
: m_isInitialized(false),
|
||||
m_ordering(SPQR_ORDERING_DEFAULT),
|
||||
m_allow_tol(SPQR_DEFAULT_TOL),
|
||||
m_tolerance (NumTraits<Scalar>::epsilon())
|
||||
: m_isInitialized(false), m_ordering(SPQR_ORDERING_DEFAULT), m_allow_tol(SPQR_DEFAULT_TOL), m_tolerance (NumTraits<Scalar>::epsilon()), m_useDefaultThreshold(true)
|
||||
{
|
||||
cholmod_l_start(&m_cc);
|
||||
}
|
||||
|
||||
SPQR(const _MatrixType& matrix)
|
||||
: m_isInitialized(false),
|
||||
m_ordering(SPQR_ORDERING_DEFAULT),
|
||||
m_allow_tol(SPQR_DEFAULT_TOL),
|
||||
m_tolerance (NumTraits<Scalar>::epsilon())
|
||||
SPQR(const _MatrixType& matrix)
|
||||
: m_isInitialized(false), m_ordering(SPQR_ORDERING_DEFAULT), m_allow_tol(SPQR_DEFAULT_TOL), m_tolerance (NumTraits<Scalar>::epsilon()), m_useDefaultThreshold(true)
|
||||
{
|
||||
cholmod_l_start(&m_cc);
|
||||
compute(matrix);
|
||||
|
|
@ -101,10 +95,26 @@ class SPQR
|
|||
if(m_isInitialized) SPQR_free();
|
||||
|
||||
MatrixType mat(matrix);
|
||||
|
||||
/* Compute the default threshold as in MatLab, see:
|
||||
* Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing
|
||||
* Sparse QR Factorization, ACM Trans. on Math. Soft. 38(1), 2011, Page 8:3
|
||||
*/
|
||||
RealScalar pivotThreshold = m_tolerance;
|
||||
if(m_useDefaultThreshold)
|
||||
{
|
||||
using std::max;
|
||||
RealScalar max2Norm = 0.0;
|
||||
for (int j = 0; j < mat.cols(); j++) max2Norm = (max)(max2Norm, mat.col(j).norm());
|
||||
if(max2Norm==RealScalar(0))
|
||||
max2Norm = RealScalar(1);
|
||||
pivotThreshold = 20 * (mat.rows() + mat.cols()) * max2Norm * NumTraits<RealScalar>::epsilon();
|
||||
}
|
||||
|
||||
cholmod_sparse A;
|
||||
A = viewAsCholmod(mat);
|
||||
Index col = matrix.cols();
|
||||
m_rank = SuiteSparseQR<Scalar>(m_ordering, m_tolerance, col, &A,
|
||||
m_rank = SuiteSparseQR<Scalar>(m_ordering, pivotThreshold, col, &A,
|
||||
&m_cR, &m_E, &m_H, &m_HPinv, &m_HTau, &m_cc);
|
||||
|
||||
if (!m_cR)
|
||||
|
|
@ -120,7 +130,7 @@ class SPQR
|
|||
/**
|
||||
* Get the number of rows of the input matrix and the Q matrix
|
||||
*/
|
||||
inline Index rows() const {return m_H->nrow; }
|
||||
inline Index rows() const {return m_cR->nrow; }
|
||||
|
||||
/**
|
||||
* Get the number of columns of the input matrix.
|
||||
|
|
@ -145,16 +155,25 @@ class SPQR
|
|||
{
|
||||
eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()");
|
||||
eigen_assert(b.cols()==1 && "This method is for vectors only");
|
||||
|
||||
|
||||
//Compute Q^T * b
|
||||
typename Dest::PlainObject y;
|
||||
typename Dest::PlainObject y, y2;
|
||||
y = matrixQ().transpose() * b;
|
||||
// Solves with the triangular matrix R
|
||||
|
||||
// Solves with the triangular matrix R
|
||||
Index rk = this->rank();
|
||||
y.topRows(rk) = this->matrixR().topLeftCorner(rk, rk).template triangularView<Upper>().solve(y.topRows(rk));
|
||||
y.bottomRows(cols()-rk).setZero();
|
||||
y2 = y;
|
||||
y.resize((std::max)(cols(),Index(y.rows())),y.cols());
|
||||
y.topRows(rk) = this->matrixR().topLeftCorner(rk, rk).template triangularView<Upper>().solve(y2.topRows(rk));
|
||||
|
||||
// Apply the column permutation
|
||||
dest.topRows(cols()) = colsPermutation() * y.topRows(cols());
|
||||
// colsPermutation() performs a copy of the permutation,
|
||||
// so let's apply it manually:
|
||||
for(Index i = 0; i < rk; ++i) dest.row(m_E[i]) = y.row(i);
|
||||
for(Index i = rk; i < cols(); ++i) dest.row(m_E[i]).setZero();
|
||||
|
||||
// y.bottomRows(y.rows()-rk).setZero();
|
||||
// dest = colsPermutation() * y.topRows(cols());
|
||||
|
||||
m_info = Success;
|
||||
}
|
||||
|
|
@ -197,7 +216,11 @@ class SPQR
|
|||
/// Set the fill-reducing ordering method to be used
|
||||
void setSPQROrdering(int ord) { m_ordering = ord;}
|
||||
/// Set the tolerance tol to treat columns with 2-norm < =tol as zero
|
||||
void setPivotThreshold(const RealScalar& tol) { m_tolerance = tol; }
|
||||
void setPivotThreshold(const RealScalar& tol)
|
||||
{
|
||||
m_useDefaultThreshold = false;
|
||||
m_tolerance = tol;
|
||||
}
|
||||
|
||||
/** \returns a pointer to the SPQR workspace */
|
||||
cholmod_common *cholmodCommon() const { return &m_cc; }
|
||||
|
|
@ -230,6 +253,7 @@ class SPQR
|
|||
mutable cholmod_dense *m_HTau; // The Householder coefficients
|
||||
mutable Index m_rank; // The rank of the matrix
|
||||
mutable cholmod_common m_cc; // Workspace and parameters
|
||||
bool m_useDefaultThreshold; // Use default threshold
|
||||
template<typename ,typename > friend struct SPQR_QProduct;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -742,6 +742,11 @@ template<typename _MatrixType, int QRPreconditioner> class JacobiSVD
|
|||
|
||||
private:
|
||||
void allocate(Index rows, Index cols, unsigned int computationOptions);
|
||||
|
||||
static void check_template_parameters()
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
|
||||
}
|
||||
|
||||
protected:
|
||||
MatrixUType m_matrixU;
|
||||
|
|
@ -762,6 +767,7 @@ template<typename _MatrixType, int QRPreconditioner> class JacobiSVD
|
|||
|
||||
internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows> m_qr_precond_morecols;
|
||||
internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols> m_qr_precond_morerows;
|
||||
MatrixType m_scaledMatrix;
|
||||
};
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner>
|
||||
|
|
@ -808,14 +814,17 @@ void JacobiSVD<MatrixType, QRPreconditioner>::allocate(Index rows, Index cols, u
|
|||
: 0);
|
||||
m_workMatrix.resize(m_diagSize, m_diagSize);
|
||||
|
||||
if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this);
|
||||
if(m_rows>m_cols) m_qr_precond_morerows.allocate(*this);
|
||||
if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this);
|
||||
if(m_rows>m_cols) m_qr_precond_morerows.allocate(*this);
|
||||
if(m_cols!=m_cols) m_scaledMatrix.resize(rows,cols);
|
||||
}
|
||||
|
||||
template<typename MatrixType, int QRPreconditioner>
|
||||
JacobiSVD<MatrixType, QRPreconditioner>&
|
||||
JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsigned int computationOptions)
|
||||
{
|
||||
check_template_parameters();
|
||||
|
||||
using std::abs;
|
||||
allocate(matrix.rows(), matrix.cols(), computationOptions);
|
||||
|
||||
|
|
@ -826,21 +835,26 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
|
|||
// limit for very small denormal numbers to be considered zero in order to avoid infinite loops (see bug 286)
|
||||
const RealScalar considerAsZero = RealScalar(2) * std::numeric_limits<RealScalar>::denorm_min();
|
||||
|
||||
// Scaling factor to reduce over/under-flows
|
||||
RealScalar scale = matrix.cwiseAbs().maxCoeff();
|
||||
if(scale==RealScalar(0)) scale = RealScalar(1);
|
||||
|
||||
/*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */
|
||||
|
||||
if(!m_qr_precond_morecols.run(*this, matrix) && !m_qr_precond_morerows.run(*this, matrix))
|
||||
if(m_rows!=m_cols)
|
||||
{
|
||||
m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize);
|
||||
m_scaledMatrix = matrix / scale;
|
||||
m_qr_precond_morecols.run(*this, m_scaledMatrix);
|
||||
m_qr_precond_morerows.run(*this, m_scaledMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize) / scale;
|
||||
if(m_computeFullU) m_matrixU.setIdentity(m_rows,m_rows);
|
||||
if(m_computeThinU) m_matrixU.setIdentity(m_rows,m_diagSize);
|
||||
if(m_computeFullV) m_matrixV.setIdentity(m_cols,m_cols);
|
||||
if(m_computeThinV) m_matrixV.setIdentity(m_cols, m_diagSize);
|
||||
}
|
||||
|
||||
// Scaling factor to reduce over/under-flows
|
||||
RealScalar scale = m_workMatrix.cwiseAbs().maxCoeff();
|
||||
if(scale==RealScalar(0)) scale = RealScalar(1);
|
||||
m_workMatrix /= scale;
|
||||
|
||||
/*** step 2. The main Jacobi SVD iteration. ***/
|
||||
|
||||
|
|
@ -861,7 +875,8 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
|
|||
using std::max;
|
||||
RealScalar threshold = (max)(considerAsZero, precision * (max)(abs(m_workMatrix.coeff(p,p)),
|
||||
abs(m_workMatrix.coeff(q,q))));
|
||||
if((max)(abs(m_workMatrix.coeff(p,q)),abs(m_workMatrix.coeff(q,p))) > threshold)
|
||||
// We compare both values to threshold instead of calling max to be robust to NaN (See bug 791)
|
||||
if(abs(m_workMatrix.coeff(p,q))>threshold || abs(m_workMatrix.coeff(q,p)) > threshold)
|
||||
{
|
||||
finished = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class AmbiVector
|
|||
delete[] m_buffer;
|
||||
if (size<1000)
|
||||
{
|
||||
Index allocSize = (size * sizeof(ListEl))/sizeof(Scalar);
|
||||
Index allocSize = (size * sizeof(ListEl) + sizeof(Scalar) - 1)/sizeof(Scalar);
|
||||
m_allocatedElements = (allocSize*sizeof(Scalar))/sizeof(ListEl);
|
||||
m_buffer = new Scalar[allocSize];
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ class AmbiVector
|
|||
Index copyElements = m_allocatedElements;
|
||||
m_allocatedElements = (std::min)(Index(m_allocatedElements*1.5),m_size);
|
||||
Index allocSize = m_allocatedElements * sizeof(ListEl);
|
||||
allocSize = allocSize/sizeof(Scalar) + (allocSize%sizeof(Scalar)>0?1:0);
|
||||
allocSize = (allocSize + sizeof(Scalar) - 1)/sizeof(Scalar);
|
||||
Scalar* newBuffer = new Scalar[allocSize];
|
||||
memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl));
|
||||
delete[] m_buffer;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,16 @@ public:
|
|||
inline BlockImpl(const XprType& xpr, int startRow, int startCol, int blockRows, int blockCols)
|
||||
: m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols)
|
||||
{}
|
||||
|
||||
inline const Scalar coeff(int row, int col) const
|
||||
{
|
||||
return m_matrix.coeff(row + IsRowMajor ? m_outerStart : 0, col +IsRowMajor ? 0 : m_outerStart);
|
||||
}
|
||||
|
||||
inline const Scalar coeff(int index) const
|
||||
{
|
||||
return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
|
||||
EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
|
||||
|
|
@ -68,6 +78,8 @@ public:
|
|||
const internal::variable_if_dynamic<Index, OuterSize> m_outerSize;
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
|
||||
private:
|
||||
Index nonZeros() const;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -82,6 +94,7 @@ class BlockImpl<SparseMatrix<_Scalar, _Options, _Index>,BlockRows,BlockCols,true
|
|||
typedef SparseMatrix<_Scalar, _Options, _Index> SparseMatrixType;
|
||||
typedef typename internal::remove_all<typename SparseMatrixType::Nested>::type _MatrixTypeNested;
|
||||
typedef Block<SparseMatrixType, BlockRows, BlockCols, true> BlockType;
|
||||
typedef Block<const SparseMatrixType, BlockRows, BlockCols, true> ConstBlockType;
|
||||
public:
|
||||
enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
|
||||
EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
|
||||
|
|
@ -223,6 +236,118 @@ public:
|
|||
else
|
||||
return Map<const Matrix<Index,OuterSize,1> >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum();
|
||||
}
|
||||
|
||||
inline Scalar& coeffRef(int row, int col)
|
||||
{
|
||||
return m_matrix.const_cast_derived().coeffRef(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));
|
||||
}
|
||||
|
||||
inline const Scalar coeff(int row, int col) const
|
||||
{
|
||||
return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));
|
||||
}
|
||||
|
||||
inline const Scalar coeff(int index) const
|
||||
{
|
||||
return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);
|
||||
}
|
||||
|
||||
const Scalar& lastCoeff() const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(BlockImpl);
|
||||
eigen_assert(nonZeros()>0);
|
||||
if(m_matrix.isCompressed())
|
||||
return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart+1]-1];
|
||||
else
|
||||
return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart]+m_matrix.innerNonZeroPtr()[m_outerStart]-1];
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
|
||||
EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
|
||||
|
||||
protected:
|
||||
|
||||
typename SparseMatrixType::Nested m_matrix;
|
||||
Index m_outerStart;
|
||||
const internal::variable_if_dynamic<Index, OuterSize> m_outerSize;
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<typename _Scalar, int _Options, typename _Index, int BlockRows, int BlockCols>
|
||||
class BlockImpl<const SparseMatrix<_Scalar, _Options, _Index>,BlockRows,BlockCols,true,Sparse>
|
||||
: public SparseMatrixBase<Block<const SparseMatrix<_Scalar, _Options, _Index>,BlockRows,BlockCols,true> >
|
||||
{
|
||||
typedef SparseMatrix<_Scalar, _Options, _Index> SparseMatrixType;
|
||||
typedef typename internal::remove_all<typename SparseMatrixType::Nested>::type _MatrixTypeNested;
|
||||
typedef Block<const SparseMatrixType, BlockRows, BlockCols, true> BlockType;
|
||||
public:
|
||||
enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
|
||||
EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
|
||||
protected:
|
||||
enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
|
||||
public:
|
||||
|
||||
class InnerIterator: public SparseMatrixType::InnerIterator
|
||||
{
|
||||
public:
|
||||
inline InnerIterator(const BlockType& xpr, Index outer)
|
||||
: SparseMatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
|
||||
{}
|
||||
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
|
||||
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
|
||||
protected:
|
||||
Index m_outer;
|
||||
};
|
||||
class ReverseInnerIterator: public SparseMatrixType::ReverseInnerIterator
|
||||
{
|
||||
public:
|
||||
inline ReverseInnerIterator(const BlockType& xpr, Index outer)
|
||||
: SparseMatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
|
||||
{}
|
||||
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
|
||||
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
|
||||
protected:
|
||||
Index m_outer;
|
||||
};
|
||||
|
||||
inline BlockImpl(const SparseMatrixType& xpr, int i)
|
||||
: m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize)
|
||||
{}
|
||||
|
||||
inline BlockImpl(const SparseMatrixType& xpr, int startRow, int startCol, int blockRows, int blockCols)
|
||||
: m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols)
|
||||
{}
|
||||
|
||||
inline const Scalar* valuePtr() const
|
||||
{ return m_matrix.valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; }
|
||||
|
||||
inline const Index* innerIndexPtr() const
|
||||
{ return m_matrix.innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; }
|
||||
|
||||
inline const Index* outerIndexPtr() const
|
||||
{ return m_matrix.outerIndexPtr() + m_outerStart; }
|
||||
|
||||
Index nonZeros() const
|
||||
{
|
||||
if(m_matrix.isCompressed())
|
||||
return std::size_t(m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()])
|
||||
- std::size_t(m_matrix.outerIndexPtr()[m_outerStart]);
|
||||
else if(m_outerSize.value()==0)
|
||||
return 0;
|
||||
else
|
||||
return Map<const Matrix<Index,OuterSize,1> >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum();
|
||||
}
|
||||
|
||||
inline const Scalar coeff(int row, int col) const
|
||||
{
|
||||
return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));
|
||||
}
|
||||
|
||||
inline const Scalar coeff(int index) const
|
||||
{
|
||||
return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);
|
||||
}
|
||||
|
||||
const Scalar& lastCoeff() const
|
||||
{
|
||||
|
|
@ -265,7 +390,8 @@ const typename SparseMatrixBase<Derived>::ConstInnerVectorReturnType SparseMatri
|
|||
* is col-major (resp. row-major).
|
||||
*/
|
||||
template<typename Derived>
|
||||
Block<Derived,Dynamic,Dynamic,true> SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize)
|
||||
typename SparseMatrixBase<Derived>::InnerVectorsReturnType
|
||||
SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize)
|
||||
{
|
||||
return Block<Derived,Dynamic,Dynamic,true>(derived(),
|
||||
IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart,
|
||||
|
|
@ -277,7 +403,8 @@ Block<Derived,Dynamic,Dynamic,true> SparseMatrixBase<Derived>::innerVectors(Inde
|
|||
* is col-major (resp. row-major). Read-only.
|
||||
*/
|
||||
template<typename Derived>
|
||||
const Block<const Derived,Dynamic,Dynamic,true> SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize) const
|
||||
const typename SparseMatrixBase<Derived>::ConstInnerVectorsReturnType
|
||||
SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize) const
|
||||
{
|
||||
return Block<const Derived,Dynamic,Dynamic,true>(derived(),
|
||||
IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart,
|
||||
|
|
@ -304,8 +431,8 @@ public:
|
|||
: m_matrix(xpr),
|
||||
m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
|
||||
m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
|
||||
m_blockRows(xpr.rows()),
|
||||
m_blockCols(xpr.cols())
|
||||
m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
|
||||
m_blockCols(BlockCols==1 ? 1 : xpr.cols())
|
||||
{}
|
||||
|
||||
/** Dynamic-size constructor
|
||||
|
|
@ -407,3 +534,4 @@ public:
|
|||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_SPARSE_BLOCK_H
|
||||
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, R
|
|||
typename Res::Scalar tmp(0);
|
||||
for(LhsInnerIterator it(lhs,j); it ;++it)
|
||||
tmp += it.value() * rhs.coeff(it.index(),c);
|
||||
res.coeffRef(j,c) = alpha * tmp;
|
||||
res.coeffRef(j,c) += alpha * tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -306,15 +306,6 @@ class DenseTimeSparseProduct
|
|||
DenseTimeSparseProduct& operator=(const DenseTimeSparseProduct&);
|
||||
};
|
||||
|
||||
// sparse * dense
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type
|
||||
SparseMatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
||||
{
|
||||
return typename SparseDenseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_SPARSEDENSEPRODUCT_H
|
||||
|
|
|
|||
|
|
@ -358,7 +358,8 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
|
|||
/** sparse * dense (returns a dense object unless it is an outer product) */
|
||||
template<typename OtherDerived>
|
||||
const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type
|
||||
operator*(const MatrixBase<OtherDerived> &other) const;
|
||||
operator*(const MatrixBase<OtherDerived> &other) const
|
||||
{ return typename SparseDenseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); }
|
||||
|
||||
/** \returns an expression of P H P^-1 where H is the matrix represented by \c *this */
|
||||
SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const
|
||||
|
|
@ -403,8 +404,10 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
|
|||
const ConstInnerVectorReturnType innerVector(Index outer) const;
|
||||
|
||||
// set of inner-vectors
|
||||
Block<Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize);
|
||||
const Block<const Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize) const;
|
||||
typedef Block<Derived,Dynamic,Dynamic,true> InnerVectorsReturnType;
|
||||
typedef Block<const Derived,Dynamic,Dynamic,true> ConstInnerVectorsReturnType;
|
||||
InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize);
|
||||
const ConstInnerVectorsReturnType innerVectors(Index outerStart, Index outerSize) const;
|
||||
|
||||
/** \internal use operator= */
|
||||
template<typename DenseDerived>
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ struct permut_sparsematrix_product_retval
|
|||
for(Index j=0; j<m_matrix.outerSize(); ++j)
|
||||
{
|
||||
Index jp = m_permutation.indices().coeff(j);
|
||||
sizes[((Side==OnTheLeft) ^ Transposed) ? jp : j] = m_matrix.innerVector(((Side==OnTheRight) ^ Transposed) ? jp : j).size();
|
||||
sizes[((Side==OnTheLeft) ^ Transposed) ? jp : j] = m_matrix.innerVector(((Side==OnTheRight) ^ Transposed) ? jp : j).nonZeros();
|
||||
}
|
||||
tmp.reserve(sizes);
|
||||
for(Index j=0; j<m_matrix.outerSize(); ++j)
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ class SparseVector
|
|||
|
||||
Index inner = IsColVector ? row : col;
|
||||
Index outer = IsColVector ? col : row;
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(outer);
|
||||
eigen_assert(outer==0);
|
||||
return insert(inner);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Upper,RowMajor>
|
|||
for(int i=lhs.rows()-1 ; i>=0 ; --i)
|
||||
{
|
||||
Scalar tmp = other.coeff(i,col);
|
||||
Scalar l_ii = 0;
|
||||
Scalar l_ii(0);
|
||||
typename Lhs::InnerIterator it(lhs, i);
|
||||
while(it && it.index()<i)
|
||||
++it;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue