Merge branch 'eigen'
parent
d35eb581ee
commit
e20561be73
564
.cproject
564
.cproject
|
@ -322,14 +322,6 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianFactor.run" path="linear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testGaussianFactor.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>
|
||||
|
@ -356,6 +348,7 @@
|
|||
</target>
|
||||
<target name="tests/testBayesTree.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>tests/testBayesTree.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -363,6 +356,7 @@
|
|||
</target>
|
||||
<target name="testBinaryBayesNet.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testBinaryBayesNet.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -410,6 +404,7 @@
|
|||
</target>
|
||||
<target name="testSymbolicBayesNet.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSymbolicBayesNet.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -417,6 +412,7 @@
|
|||
</target>
|
||||
<target name="tests/testSymbolicFactor.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>tests/testSymbolicFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -424,6 +420,7 @@
|
|||
</target>
|
||||
<target name="testSymbolicFactorGraph.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSymbolicFactorGraph.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -439,11 +436,20 @@
|
|||
</target>
|
||||
<target name="tests/testBayesTree" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>tests/testBayesTree</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianFactor.run" path="linear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testGaussianFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -478,7 +484,6 @@
|
|||
</target>
|
||||
<target name="testGraph.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testGraph.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -574,7 +579,6 @@
|
|||
</target>
|
||||
<target name="testInference.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testInference.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -582,7 +586,6 @@
|
|||
</target>
|
||||
<target name="testGaussianBayesNet.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testGaussianBayesNet.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -590,7 +593,6 @@
|
|||
</target>
|
||||
<target name="testGaussianFactor.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testGaussianFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -598,7 +600,6 @@
|
|||
</target>
|
||||
<target name="testJunctionTree.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testJunctionTree.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -606,7 +607,6 @@
|
|||
</target>
|
||||
<target name="testSymbolicBayesNet.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSymbolicBayesNet.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -614,7 +614,6 @@
|
|||
</target>
|
||||
<target name="testSymbolicFactorGraph.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSymbolicFactorGraph.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -692,6 +691,22 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/gtsam/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="check" path="build/gtsam/nonlinear" 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="check" path="build/geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -748,14 +763,6 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/gtsam/inference" 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="vSFMexample.run" path="build/examples/vSLAMexample" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -764,6 +771,14 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/gtsam/inference" 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="testVSLAMGraph" path="build/slam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -820,22 +835,6 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianFactorGraph" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testGaussianFactorGraph</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianJunctionTree" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testGaussianJunctionTree</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testInference.run" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -876,6 +875,14 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianFactor.run" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testGaussianFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="SimpleRotation.run" path="examples" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -974,6 +981,7 @@
|
|||
</target>
|
||||
<target name="testErrors.run" path="linear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testErrors.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -1267,6 +1275,14 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/gtsam/geometry" 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="all" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -1349,7 +1365,6 @@
|
|||
</target>
|
||||
<target name="testSimulated2DOriented.run" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSimulated2DOriented.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -1389,7 +1404,6 @@
|
|||
</target>
|
||||
<target name="testSimulated2D.run" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSimulated2D.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -1397,7 +1411,6 @@
|
|||
</target>
|
||||
<target name="testSimulated3D.run" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSimulated3D.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -1427,6 +1440,62 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testVector.run" path="build/gtsam/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testVector.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testMatrix.run" path="build/gtsam/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testMatrix.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/gtsam/base" 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/testNumericalDerivative.run" path="build/gtsam/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testNumericalDerivative.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testBlockMatrices.run" path="build/gtsam/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testBlockMatrices.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean" path="build/gtsam/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testCholesky.run" path="build/gtsam/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testCholesky.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testVectorValues.run" path="build/gtsam/linear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -1459,6 +1528,38 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/gtsam/linear" 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/testGaussianConditional.run" path="build/gtsam/linear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testGaussianConditional.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testGaussianFactorGraph.run" path="build/gtsam/linear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testGaussianFactorGraph.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testGaussianJunctionTree.run" path="build/gtsam/linear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testGaussianJunctionTree.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="SimpleRotation.run" path="build/examples" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -1501,7 +1602,6 @@
|
|||
</target>
|
||||
<target name="tests/testGaussianISAM2" path="build/slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>tests/testGaussianISAM2</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -1523,6 +1623,46 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="install" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>install</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="" 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="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="dist" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>dist</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testRot3.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -1619,54 +1759,6 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="install" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>install</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="" 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="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="dist" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>dist</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/wrap" 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="check" path="build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -1699,6 +1791,14 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/wrap" 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>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
|
@ -2021,14 +2121,6 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianFactor.run" path="linear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testGaussianFactor.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>
|
||||
|
@ -2055,6 +2147,7 @@
|
|||
</target>
|
||||
<target name="tests/testBayesTree.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>tests/testBayesTree.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2062,6 +2155,7 @@
|
|||
</target>
|
||||
<target name="testBinaryBayesNet.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testBinaryBayesNet.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2109,6 +2203,7 @@
|
|||
</target>
|
||||
<target name="testSymbolicBayesNet.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSymbolicBayesNet.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2116,6 +2211,7 @@
|
|||
</target>
|
||||
<target name="tests/testSymbolicFactor.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>tests/testSymbolicFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2123,6 +2219,7 @@
|
|||
</target>
|
||||
<target name="testSymbolicFactorGraph.run" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSymbolicFactorGraph.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2138,11 +2235,20 @@
|
|||
</target>
|
||||
<target name="tests/testBayesTree" path="inference" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>tests/testBayesTree</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianFactor.run" path="linear/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testGaussianFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -2177,7 +2283,6 @@
|
|||
</target>
|
||||
<target name="testGraph.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testGraph.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2273,7 +2378,6 @@
|
|||
</target>
|
||||
<target name="testInference.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testInference.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2281,7 +2385,6 @@
|
|||
</target>
|
||||
<target name="testGaussianBayesNet.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testGaussianBayesNet.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2289,7 +2392,6 @@
|
|||
</target>
|
||||
<target name="testGaussianFactor.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testGaussianFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2297,7 +2399,6 @@
|
|||
</target>
|
||||
<target name="testJunctionTree.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testJunctionTree.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2305,7 +2406,6 @@
|
|||
</target>
|
||||
<target name="testSymbolicBayesNet.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSymbolicBayesNet.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2313,7 +2413,6 @@
|
|||
</target>
|
||||
<target name="testSymbolicFactorGraph.run" path="tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSymbolicFactorGraph.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2391,6 +2490,22 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/gtsam/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="check" path="build/gtsam/nonlinear" 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="check" path="build/geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -2447,14 +2562,6 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/gtsam/inference" 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="vSFMexample.run" path="build/examples/vSLAMexample" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -2463,6 +2570,14 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/gtsam/inference" 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="testVSLAMGraph" path="build/slam/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -2519,22 +2634,6 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianFactorGraph" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testGaussianFactorGraph</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianJunctionTree" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testGaussianJunctionTree</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testInference.run" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -2575,6 +2674,14 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testGaussianFactor.run" path="build/tests" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>testGaussianFactor.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="SimpleRotation.run" path="examples" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -2673,6 +2780,7 @@
|
|||
</target>
|
||||
<target name="testErrors.run" path="linear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testErrors.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -2966,6 +3074,14 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/gtsam/geometry" 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="all" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -3048,7 +3164,6 @@
|
|||
</target>
|
||||
<target name="testSimulated2DOriented.run" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSimulated2DOriented.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -3088,7 +3203,6 @@
|
|||
</target>
|
||||
<target name="testSimulated2D.run" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSimulated2D.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -3096,7 +3210,6 @@
|
|||
</target>
|
||||
<target name="testSimulated3D.run" path="slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>testSimulated3D.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -3126,6 +3239,62 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testVector.run" path="build/gtsam/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testVector.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testMatrix.run" path="build/gtsam/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testMatrix.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/gtsam/base" 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/testNumericalDerivative.run" path="build/gtsam/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testNumericalDerivative.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testBlockMatrices.run" path="build/gtsam/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testBlockMatrices.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean" path="build/gtsam/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testCholesky.run" path="build/gtsam/base" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testCholesky.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testVectorValues.run" path="build/gtsam/linear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -3158,6 +3327,38 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/gtsam/linear" 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/testGaussianConditional.run" path="build/gtsam/linear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testGaussianConditional.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testGaussianFactorGraph.run" path="build/gtsam/linear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testGaussianFactorGraph.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="tests/testGaussianJunctionTree.run" path="build/gtsam/linear" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>tests/testGaussianJunctionTree.run</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="SimpleRotation.run" path="build/examples" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -3200,7 +3401,6 @@
|
|||
</target>
|
||||
<target name="tests/testGaussianISAM2" path="build/slam" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments/>
|
||||
<buildTarget>tests/testGaussianISAM2</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
|
@ -3222,6 +3422,46 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="install" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>install</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="" 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="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="dist" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>dist</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="testRot3.run" path="geometry" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -3318,54 +3558,6 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="install" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>install</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="" 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="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="dist" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
<buildTarget>dist</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/wrap" 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="check" path="build" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>make</buildCommand>
|
||||
<buildArguments>-j2</buildArguments>
|
||||
|
@ -3398,6 +3590,14 @@
|
|||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="check" path="build/wrap" 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>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
|
|
118
configure.ac
118
configure.ac
|
@ -13,9 +13,38 @@ AC_CONFIG_SRCDIR([gtsam/inference/SymbolicFactorGraph.cpp])
|
|||
AC_CONFIG_SRCDIR([gtsam/linear/GaussianFactor.cpp])
|
||||
AC_CONFIG_SRCDIR([gtsam/nonlinear/NonlinearOptimizer.cpp])
|
||||
AC_CONFIG_SRCDIR([gtsam/slam/pose2SLAM.cpp])
|
||||
AC_CONFIG_SRCDIR([tests/testSQP.cpp])
|
||||
AC_CONFIG_SRCDIR([tests/testTupleValues.cpp])
|
||||
AC_CONFIG_SRCDIR([examples/SimpleRotation.cpp])
|
||||
|
||||
# pull in all subdirectories of Eigen - FIXME: find a better way of handling this
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Cholesky/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Core/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Core/arch/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Core/arch/AltiVec/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Core/arch/Default/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Core/arch/NEON/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Core/arch/SSE/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Core/products/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Core/util/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Eigen2Support/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Eigen2Support/Geometry/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Eigenvalues/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Geometry/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Geometry/arch/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Householder/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/QR/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/SVD/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Jacobi/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/misc/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/Sparse/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/LU/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/LU/arch/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/plugins/Makefile.am])
|
||||
AC_CONFIG_SRCDIR([gtsam/3rdparty/Eigen/src/StlSupport/Makefile.am])
|
||||
|
||||
# Check for OS
|
||||
AC_CANONICAL_HOST # needs to be called at some point earlier
|
||||
AM_CONDITIONAL([DARWIN], [case $host_os in darwin*) true;; *) false;; esac])
|
||||
|
@ -45,46 +74,6 @@ case $host_os in
|
|||
;;
|
||||
esac
|
||||
|
||||
# enable BLAS with general purpose script
|
||||
AC_ARG_ENABLE([blas],
|
||||
[ --enable-blas Enable external BLAS library],
|
||||
[case "${enableval}" in
|
||||
yes) blas=true ;;
|
||||
no) blas=false ;;
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-blas]) ;;
|
||||
esac],[blas=true])
|
||||
ak
|
||||
AM_CONDITIONAL([USE_BLAS], test x$blas = xtrue)
|
||||
AM_CONDITIONAL([USE_BLAS_MACOS], [test x$blas = xtrue && test x$ISMAC = xtrue])
|
||||
AM_CONDITIONAL([USE_BLAS_LINUX], [test x$blas = xtrue && test x$ISMAC = xfalse])
|
||||
|
||||
# enable LAPACK
|
||||
AC_ARG_ENABLE([lapack],
|
||||
[ --enable-lapack Enable external LAPACK library],
|
||||
[case "${enableval}" in
|
||||
yes) lapack=true ;;
|
||||
no) lapack=false ;;
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-lapack]) ;;
|
||||
esac],[lapack=true])
|
||||
|
||||
AM_CONDITIONAL([USE_LAPACK], test x$lapack = xtrue)
|
||||
AM_CONDITIONAL([USE_LAPACK_MACOS], [test x$lapack = xtrue && test x$ISMAC = xtrue])
|
||||
AM_CONDITIONAL([USE_LAPACK_LINUX], [test x$lapack = xtrue && test x$ISMAC = xfalse])
|
||||
|
||||
# On Mac, we use the Accelerate framework for BLAS/LAPACK
|
||||
AM_CONDITIONAL([USE_ACCELERATE_MACOS], [(test x$lapack = xtrue || test x$blas = xtrue) && test x$ISMAC = xtrue])
|
||||
|
||||
#enable SparseQR for linear solving
|
||||
AC_ARG_ENABLE([spqr],
|
||||
[ --enable-spqr Enable SparseQR library support],
|
||||
[case "${enableval}" in
|
||||
yes) spqr=true ;;
|
||||
no) spqr=false ;;
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-spqr]) ;;
|
||||
esac],[spqr=false])
|
||||
|
||||
AM_CONDITIONAL([USE_SPQR], [test x$spqr = xtrue])
|
||||
|
||||
# enable profiling
|
||||
AC_ARG_ENABLE([profiling],
|
||||
[ --enable-profiling Enable profiling],
|
||||
|
@ -167,13 +156,42 @@ AC_ARG_WITH([ccolamd-lib],
|
|||
[CCOLAMDLib=${HOME}/lib])
|
||||
AC_SUBST([CCOLAMDLib])
|
||||
|
||||
# For now we require blas, atlas, and lapack
|
||||
#AM_COND_IF([test x$ISMAC = xtrue],
|
||||
# [LINALG_CPPFLAGS="-I/System/Library/Frameworks/vecLib.framework/Headers ${CCOLAMDInc} -DGT_USE_LAPACK"],
|
||||
# [LINALG_CPPFLAGS="${CCOLAMDInc} -DGT_USE_LAPACK"])
|
||||
#AM_COND_IF([test x$ISMAC = xtrue],
|
||||
# [LINALG_LDFLAGS="-Wl,/System/Library/Frameworks/Accelerate.framework/Accelerate ${CCOLAMDLib}"],
|
||||
# [LINALG_LDFLAGS="-lcblas -latlas -llapack ${CCOLAMDLib}"])
|
||||
|
||||
AC_CONFIG_FILES([CppUnitLite/Makefile gtsam/base/Makefile gtsam/geometry/Makefile gtsam/inference/Makefile gtsam/linear/Makefile gtsam/nonlinear/Makefile gtsam/slam/Makefile gtsam/Makefile tests/Makefile examples/Makefile examples/vSLAMexample/Makefile Makefile])
|
||||
AC_CONFIG_FILES([CppUnitLite/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Cholesky/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Core/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Core/arch/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Core/arch/AltiVec/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Core/arch/Default/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Core/arch/NEON/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Core/arch/SSE/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Core/products/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Core/util/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Eigenvalues/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Geometry/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Geometry/arch/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Householder/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/QR/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/SVD/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Jacobi/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/misc/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Sparse/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/LU/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/LU/arch/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/plugins/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/StlSupport/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Eigen2Support/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Eigen2Support/Geometry/Makefile \
|
||||
gtsam/3rdparty/Eigen/src/Makefile \
|
||||
gtsam/3rdparty/Eigen/Makefile \
|
||||
gtsam/3rdparty/Makefile \
|
||||
gtsam/base/Makefile \
|
||||
gtsam/geometry/Makefile \
|
||||
gtsam/inference/Makefile \
|
||||
gtsam/linear/Makefile \
|
||||
gtsam/nonlinear/Makefile \
|
||||
gtsam/slam/Makefile gtsam/Makefile \
|
||||
tests/Makefile \
|
||||
examples/Makefile \
|
||||
examples/vSLAMexample/Makefile \
|
||||
Makefile])
|
||||
AC_OUTPUT
|
||||
|
|
|
@ -27,22 +27,6 @@ AM_LDFLAGS = $(BOOST_LDFLAGS)
|
|||
LDADD = ../gtsam/libgtsam.la
|
||||
AM_DEFAULT_SOURCE_EXT = .cpp
|
||||
|
||||
if USE_BLAS_LINUX
|
||||
AM_LDFLAGS += -lcblas -latlas
|
||||
endif
|
||||
|
||||
if USE_LAPACK
|
||||
AM_CPPFLAGS += -DGT_USE_LAPACK
|
||||
endif
|
||||
|
||||
if USE_LAPACK_LINUX
|
||||
AM_LDFLAGS += -llapack
|
||||
endif
|
||||
|
||||
if USE_ACCELERATE_MACOS
|
||||
AM_LDFLAGS += -Wl,/System/Library/Frameworks/Accelerate.framework/Accelerate
|
||||
endif
|
||||
|
||||
# rule to run an executable
|
||||
%.run: % $(LDADD)
|
||||
./$^
|
||||
|
|
|
@ -33,22 +33,6 @@ AM_LDFLAGS = $(BOOST_LDFLAGS)
|
|||
LDADD = ../../gtsam/libgtsam.la
|
||||
AM_DEFAULT_SOURCE_EXT = .cpp
|
||||
|
||||
if USE_BLAS_LINUX
|
||||
AM_LDFLAGS += -lcblas -latlas
|
||||
endif
|
||||
|
||||
if USE_LAPACK
|
||||
AM_CPPFLAGS += -DGT_USE_LAPACK
|
||||
endif
|
||||
|
||||
if USE_LAPACK_LINUX
|
||||
AM_LDFLAGS += -llapack
|
||||
endif
|
||||
|
||||
if USE_ACCELERATE_MACOS
|
||||
AM_LDFLAGS += -Wl,/System/Library/Frameworks/Accelerate.framework/Accelerate
|
||||
endif
|
||||
|
||||
# rule to run an executable
|
||||
%.run: % $(LDADD)
|
||||
./$^
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS = src
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
# add primary headers
|
||||
headers = Array Cholesky Core Dense Eigen Eigen2Support Eigenvalues
|
||||
headers += Geometry Householder Jacobi LeastSquares LU QR QtAlignedMalloc
|
||||
headers += Sparse StdDeque StdList StdVector SVD
|
||||
|
||||
Eigendir = $(pkgincludedir)/3rdparty/Eigen
|
||||
Eigen_includedir = $(includedir)/gtsam/3rdparty/Eigen
|
||||
Eigen_HEADERS = $(headers)
|
|
@ -1,7 +0,0 @@
|
|||
file(GLOB Eigen_src_subdirectories "*")
|
||||
escape_string_as_regex(ESCAPED_CMAKE_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
foreach(f ${Eigen_src_subdirectories})
|
||||
if(NOT f MATCHES "\\.txt" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/[.].+" )
|
||||
add_subdirectory(${f})
|
||||
endif()
|
||||
endforeach()
|
|
@ -1,6 +0,0 @@
|
|||
FILE(GLOB Eigen_Cholesky_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_Cholesky_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Cholesky COMPONENT Devel
|
||||
)
|
|
@ -0,0 +1,21 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
# add headers from src folder for Eigen
|
||||
#Cholesky:
|
||||
headers = LDLT.h
|
||||
headers += LLT.h
|
||||
|
||||
Choleskydir = $(pkgincludedir)/3rdparty/Eigen/src/Cholesky
|
||||
Cholesky_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Cholesky
|
||||
Cholesky_HEADERS = $(headers)
|
|
@ -1,10 +0,0 @@
|
|||
FILE(GLOB Eigen_Core_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_Core_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Core COMPONENT Devel
|
||||
)
|
||||
|
||||
ADD_SUBDIRECTORY(products)
|
||||
ADD_SUBDIRECTORY(util)
|
||||
ADD_SUBDIRECTORY(arch)
|
|
@ -0,0 +1,78 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS = arch products util
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
# add headers from src folder for Eigen
|
||||
headers =
|
||||
|
||||
#Core:
|
||||
headers += ArrayBase.h
|
||||
headers += Array.h
|
||||
headers += ArrayWrapper.h
|
||||
headers += Assign.h
|
||||
headers += BandMatrix.h
|
||||
headers += Block.h
|
||||
headers += BooleanRedux.h
|
||||
headers += CommaInitializer.h
|
||||
headers += CwiseBinaryOp.h
|
||||
headers += CwiseNullaryOp.h
|
||||
headers += CwiseUnaryOp.h
|
||||
headers += CwiseUnaryView.h
|
||||
headers += DenseBase.h
|
||||
headers += DenseCoeffsBase.h
|
||||
headers += DenseStorage.h
|
||||
headers += Diagonal.h
|
||||
headers += DiagonalMatrix.h
|
||||
headers += DiagonalProduct.h
|
||||
headers += Dot.h
|
||||
headers += EigenBase.h
|
||||
headers += Flagged.h
|
||||
headers += ForceAlignedAccess.h
|
||||
headers += Functors.h
|
||||
headers += Fuzzy.h
|
||||
headers += GenericPacketMath.h
|
||||
headers += GlobalFunctions.h
|
||||
headers += IO.h
|
||||
headers += MapBase.h
|
||||
headers += Map.h
|
||||
headers += MathFunctions.h
|
||||
headers += MatrixBase.h
|
||||
headers += Matrix.h
|
||||
headers += NestByValue.h
|
||||
headers += NoAlias.h
|
||||
headers += NumTraits.h
|
||||
headers += PermutationMatrix.h
|
||||
headers += PlainObjectBase.h
|
||||
headers += ProductBase.h
|
||||
headers += Product.h
|
||||
headers += Random.h
|
||||
headers += Redux.h
|
||||
headers += Replicate.h
|
||||
headers += ReturnByValue.h
|
||||
headers += Reverse.h
|
||||
headers += Select.h
|
||||
headers += SelfAdjointView.h
|
||||
headers += SelfCwiseBinaryOp.h
|
||||
headers += SolveTriangular.h
|
||||
headers += StableNorm.h
|
||||
headers += Stride.h
|
||||
headers += Swap.h
|
||||
headers += Transpose.h
|
||||
headers += Transpositions.h
|
||||
headers += TriangularMatrix.h
|
||||
headers += VectorBlock.h
|
||||
headers += VectorwiseOp.h
|
||||
headers += Visitor.h
|
||||
|
||||
Coredir = $(pkgincludedir)/3rdparty/Eigen/src/Core
|
||||
Core_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Core
|
||||
Core_HEADERS = $(headers)
|
|
@ -0,0 +1,23 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
|
||||
# Core/arch/AltiVec:
|
||||
headers += Complex.h
|
||||
headers += PacketMath.h
|
||||
|
||||
AltiVecdir = $(pkgincludedir)/3rdparty/Eigen/src/Core/arch/AltiVec
|
||||
AltiVec_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Core/arch/AltiVec
|
||||
AltiVec_HEADERS = $(headers)
|
|
@ -1,4 +0,0 @@
|
|||
ADD_SUBDIRECTORY(SSE)
|
||||
ADD_SUBDIRECTORY(AltiVec)
|
||||
ADD_SUBDIRECTORY(NEON)
|
||||
ADD_SUBDIRECTORY(Default)
|
|
@ -0,0 +1,21 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# Core/arch/Default:
|
||||
headers += Settings.h
|
||||
|
||||
Defaultdir = $(pkgincludedir)/3rdparty/Eigen/src/Core/arch/Default
|
||||
Default_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Core/arch/Default
|
||||
Default_HEADERS = $(headers)
|
|
@ -0,0 +1,4 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS = AltiVec Default NEON SSE
|
|
@ -0,0 +1,22 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# Core/arch/NEON:
|
||||
headers += Complex.h
|
||||
headers += PacketMath.h
|
||||
|
||||
NEONdir = $(pkgincludedir)/3rdparty/Eigen/src/Core/arch/NEON
|
||||
NEON_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Core/arch/NEON
|
||||
NEON_HEADERS = $(headers)
|
|
@ -0,0 +1,22 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
# Core/arch/SSE:
|
||||
headers += Complex.h
|
||||
headers += MathFunctions.h
|
||||
headers += PacketMath.h
|
||||
|
||||
SSEdir = $(pkgincludedir)/3rdparty/Eigen/src/Core/arch/SSE
|
||||
SSE_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Core/arch/SSE
|
||||
SSE_HEADERS = $(headers)
|
|
@ -0,0 +1,34 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# Core/products:
|
||||
headers += CoeffBasedProduct.h
|
||||
headers += GeneralBlockPanelKernel.h
|
||||
headers += GeneralMatrixMatrix.h
|
||||
headers += GeneralMatrixMatrixTriangular.h
|
||||
headers += GeneralMatrixVector.h
|
||||
headers += Parallelizer.h
|
||||
headers += SelfadjointMatrixMatrix.h
|
||||
headers += SelfadjointMatrixVector.h
|
||||
headers += SelfadjointProduct.h
|
||||
headers += SelfadjointRank2Update.h
|
||||
headers += TriangularMatrixMatrix.h
|
||||
headers += TriangularMatrixVector.h
|
||||
headers += TriangularSolverMatrix.h
|
||||
headers += TriangularSolverVector.h
|
||||
|
||||
productsdir = $(pkgincludedir)/3rdparty/Eigen/src/Core/products
|
||||
products_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Core/products
|
||||
products_HEADERS = $(headers)
|
|
@ -0,0 +1,30 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# Core/util:
|
||||
headers += BlasUtil.h
|
||||
headers += Constants.h
|
||||
headers += DisableStupidWarnings.h
|
||||
headers += ForwardDeclarations.h
|
||||
headers += Macros.h
|
||||
headers += Memory.h
|
||||
headers += Meta.h
|
||||
headers += ReenableStupidWarnings.h
|
||||
headers += StaticAssert.h
|
||||
headers += XprHelper.h
|
||||
|
||||
utildir = $(pkgincludedir)/3rdparty/Eigen/src/Core/util
|
||||
util_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Core/util
|
||||
util_HEADERS = $(headers)
|
|
@ -1,8 +0,0 @@
|
|||
FILE(GLOB Eigen_Eigen2Support_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_Eigen2Support_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Eigen2Support COMPONENT Devel
|
||||
)
|
||||
|
||||
ADD_SUBDIRECTORY(Geometry)
|
|
@ -1,6 +0,0 @@
|
|||
FILE(GLOB Eigen_Eigen2Support_Geometry_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_Eigen2Support_Geometry_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Eigen2Support/Geometry
|
||||
)
|
|
@ -0,0 +1,31 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# Eigen2SupportGeometry:
|
||||
headers += AlignedBox.h
|
||||
headers += All.h
|
||||
headers += AngleAxis.h
|
||||
headers += Hyperplane.h
|
||||
headers += ParametrizedLine.h
|
||||
headers += Quaternion.h
|
||||
headers += Rotation2D.h
|
||||
headers += RotationBase.h
|
||||
headers += Scaling.h
|
||||
headers += Transform.h
|
||||
headers += Translation.h
|
||||
|
||||
Geometrydir = $(pkgincludedir)/3rdparty/Eigen/src/Eigen2Support/Geometry
|
||||
Geometry_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Eigen2Support/Geometry
|
||||
Geometry_HEADERS = $(headers)
|
|
@ -0,0 +1,35 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS = Geometry
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# Eigen2Support:
|
||||
headers += Block.h
|
||||
headers += Cwise.h
|
||||
headers += CwiseOperators.h
|
||||
headers += Lazy.h
|
||||
headers += LeastSquares.h
|
||||
headers += LU.h
|
||||
headers += Macros.h
|
||||
headers += MathFunctions.h
|
||||
headers += Memory.h
|
||||
headers += Meta.h
|
||||
headers += Minor.h
|
||||
headers += QR.h
|
||||
headers += SVD.h
|
||||
headers += TriangularSolver.h
|
||||
headers += VectorBlock.h
|
||||
|
||||
Eigen2Supportdir = $(pkgincludedir)/3rdparty/Eigen/src/Eigen2Support
|
||||
Eigen2Support_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Eigen2Support
|
||||
Eigen2Support_HEADERS = $(headers)
|
|
@ -0,0 +1,30 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# Eigenvalues:
|
||||
headers += ComplexEigenSolver.h
|
||||
headers += ComplexSchur.h
|
||||
headers += EigenSolver.h
|
||||
headers += EigenvaluesCommon.h
|
||||
headers += GeneralizedSelfAdjointEigenSolver.h
|
||||
headers += HessenbergDecomposition.h
|
||||
headers += MatrixBaseEigenvalues.h
|
||||
headers += RealSchur.h
|
||||
headers += SelfAdjointEigenSolver.h
|
||||
headers += Tridiagonalization.h
|
||||
|
||||
Eigenvaluesdir = $(pkgincludedir)/3rdparty/Eigen/src/Eigenvalues
|
||||
Eigenvalues_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Eigenvalues
|
||||
Eigenvalues_HEADERS = $(headers)
|
|
@ -0,0 +1,34 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS = arch
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# Geometry:
|
||||
headers += AlignedBox.h
|
||||
headers += AngleAxis.h
|
||||
headers += EulerAngles.h
|
||||
headers += Homogeneous.h
|
||||
headers += Hyperplane.h
|
||||
headers += OrthoMethods.h
|
||||
headers += ParametrizedLine.h
|
||||
headers += Quaternion.h
|
||||
headers += Rotation2D.h
|
||||
headers += RotationBase.h
|
||||
headers += Scaling.h
|
||||
headers += Transform.h
|
||||
headers += Translation.h
|
||||
headers += Umeyama.h
|
||||
|
||||
Geometrydir = $(pkgincludedir)/3rdparty/Eigen/src/Geometry
|
||||
Geometry_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Geometry
|
||||
Geometry_HEADERS = $(headers)
|
|
@ -1,6 +0,0 @@
|
|||
FILE(GLOB Eigen_Geometry_arch_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_Geometry_arch_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Geometry/arch COMPONENT Devel
|
||||
)
|
|
@ -0,0 +1,22 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
# add primary headers
|
||||
headers =
|
||||
|
||||
# Geometry/arch:
|
||||
headers += Geometry_SSE.h
|
||||
|
||||
archdir = $(pkgincludedir)/3rdparty/Eigen/src/Geometry/arch
|
||||
arch_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Geometry/arch
|
||||
arch_HEADERS = $(headers)
|
|
@ -1,6 +0,0 @@
|
|||
FILE(GLOB Eigen_Householder_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_Householder_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Householder COMPONENT Devel
|
||||
)
|
|
@ -0,0 +1,23 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# Householder:
|
||||
headers += BlockHouseholder.h
|
||||
headers += Householder.h
|
||||
headers += HouseholderSequence.h
|
||||
|
||||
Householderdir = $(pkgincludedir)/3rdparty/Eigen/src/Householder
|
||||
Householder_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Householder
|
||||
Householder_HEADERS = $(headers)
|
|
@ -1,6 +0,0 @@
|
|||
FILE(GLOB Eigen_Jacobi_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_Jacobi_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Jacobi COMPONENT Devel
|
||||
)
|
|
@ -0,0 +1,20 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
# add primary headers
|
||||
# Jacobi
|
||||
headers = Jacobi.h
|
||||
|
||||
Jacobidir = $(pkgincludedir)/3rdparty/Eigen/src/Jacobi
|
||||
Jacobi_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Jacobi
|
||||
Jacobi_HEADERS = $(headers)
|
|
@ -1,8 +0,0 @@
|
|||
FILE(GLOB Eigen_LU_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_LU_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/LU COMPONENT Devel
|
||||
)
|
||||
|
||||
ADD_SUBDIRECTORY(arch)
|
|
@ -0,0 +1,24 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS = arch
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# LU:
|
||||
headers += Determinant.h
|
||||
headers += FullPivLU.h
|
||||
headers += Inverse.h
|
||||
headers += PartialPivLU.h
|
||||
|
||||
LUdir = $(pkgincludedir)/3rdparty/Eigen/src/LU
|
||||
LU_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/LU
|
||||
LU_HEADERS = $(headers)
|
|
@ -1,6 +0,0 @@
|
|||
FILE(GLOB Eigen_LU_arch_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_LU_arch_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/LU/arch COMPONENT Devel
|
||||
)
|
|
@ -0,0 +1,19 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
# LU/arch:
|
||||
headers = Inverse_SSE.h
|
||||
|
||||
archdir = $(pkgincludedir)/3rdparty/Eigen/src/LU/arch
|
||||
arch_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/LU/arch
|
||||
arch_HEADERS = $(headers)
|
|
@ -0,0 +1,9 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS = Cholesky Core Eigenvalues
|
||||
SUBDIRS += Geometry
|
||||
SUBDIRS += Jacobi misc Sparse
|
||||
SUBDIRS += LU plugins StlSupport
|
||||
SUBDIRS += Householder QR SVD
|
||||
SUBDIRS += Eigen2Support
|
|
@ -1,6 +0,0 @@
|
|||
FILE(GLOB Eigen_QR_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_QR_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/QR COMPONENT Devel
|
||||
)
|
|
@ -0,0 +1,23 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# QR:
|
||||
headers += ColPivHouseholderQR.h
|
||||
headers += FullPivHouseholderQR.h
|
||||
headers += HouseholderQR.h
|
||||
|
||||
QRdir = $(pkgincludedir)/3rdparty/Eigen/src/QR
|
||||
QR_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/QR
|
||||
QR_HEADERS = $(headers)
|
|
@ -1,6 +0,0 @@
|
|||
FILE(GLOB Eigen_SVD_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_SVD_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/SVD COMPONENT Devel
|
||||
)
|
|
@ -0,0 +1,22 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
#SVD:
|
||||
headers += JacobiSVD.h
|
||||
headers += UpperBidiagonalization.h
|
||||
|
||||
SVDdir = $(pkgincludedir)/3rdparty/Eigen/src/SVD
|
||||
SVD_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/SVD
|
||||
SVD_HEADERS = $(headers)
|
|
@ -1,6 +0,0 @@
|
|||
FILE(GLOB Eigen_Sparse_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_Sparse_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Sparse COMPONENT Devel
|
||||
)
|
|
@ -0,0 +1,45 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# Sparse:
|
||||
headers += AmbiVector.h
|
||||
headers += CompressedStorage.h
|
||||
headers += CoreIterators.h
|
||||
headers += DynamicSparseMatrix.h
|
||||
headers += MappedSparseMatrix.h
|
||||
headers += SparseAssign.h
|
||||
headers += SparseBlock.h
|
||||
headers += SparseCwiseBinaryOp.h
|
||||
headers += SparseCwiseUnaryOp.h
|
||||
headers += SparseDenseProduct.h
|
||||
headers += SparseDiagonalProduct.h
|
||||
headers += SparseDot.h
|
||||
headers += SparseFuzzy.h
|
||||
headers += SparseMatrixBase.h
|
||||
headers += SparseMatrix.h
|
||||
headers += SparseProduct.h
|
||||
headers += SparseRedux.h
|
||||
headers += SparseSelfAdjointView.h
|
||||
headers += SparseSparseProduct.h
|
||||
headers += SparseTranspose.h
|
||||
headers += SparseTriangularView.h
|
||||
headers += SparseUtil.h
|
||||
headers += SparseVector.h
|
||||
headers += SparseView.h
|
||||
headers += TriangularSolver.h
|
||||
|
||||
Sparsedir = $(pkgincludedir)/3rdparty/Eigen/src/Sparse
|
||||
Sparse_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/Sparse
|
||||
Sparse_HEADERS = $(headers)
|
|
@ -1,6 +0,0 @@
|
|||
FILE(GLOB Eigen_StlSupport_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_StlSupport_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/StlSupport COMPONENT Devel
|
||||
)
|
|
@ -0,0 +1,24 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# StlSupport:
|
||||
headers += details.h
|
||||
headers += StdDeque.h
|
||||
headers += StdList.h
|
||||
headers += StdVector.h
|
||||
|
||||
StlSupportdir = $(pkgincludedir)/3rdparty/Eigen/src/StlSupport
|
||||
StlSupport_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/StlSupport
|
||||
StlSupport_HEADERS = $(headers)
|
|
@ -1,6 +0,0 @@
|
|||
FILE(GLOB Eigen_misc_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_misc_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/misc COMPONENT Devel
|
||||
)
|
|
@ -0,0 +1,23 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# misc:
|
||||
headers += Image.h
|
||||
headers += Kernel.h
|
||||
headers += Solve.h
|
||||
|
||||
miscdir = $(pkgincludedir)/3rdparty/Eigen/src/misc
|
||||
misc_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/misc
|
||||
misc_HEADERS = $(headers)
|
|
@ -1,6 +0,0 @@
|
|||
FILE(GLOB Eigen_plugins_SRCS "*.h")
|
||||
|
||||
INSTALL(FILES
|
||||
${Eigen_plugins_SRCS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/plugins COMPONENT Devel
|
||||
)
|
|
@ -0,0 +1,27 @@
|
|||
# Eigen build/install - just need to copy header files into correct place
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS =
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
SUBLIBS =
|
||||
|
||||
# use nostdinc to turn off -I. and -I.., we do not need them because
|
||||
# header files are qualified so they can be included in external projects.
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
headers =
|
||||
|
||||
# plugins:
|
||||
headers += ArrayCwiseBinaryOps.h
|
||||
headers += ArrayCwiseUnaryOps.h
|
||||
headers += BlockMethods.h
|
||||
headers += CommonCwiseBinaryOps.h
|
||||
headers += CommonCwiseUnaryOps.h
|
||||
headers += MatrixCwiseBinaryOps.h
|
||||
headers += MatrixCwiseUnaryOps.h
|
||||
|
||||
pluginsdir = $(pkgincludedir)/3rdparty/Eigen/src/plugins
|
||||
plugins_includedir = $(includedir)/gtsam/3rdparty/Eigen/src/plugins
|
||||
plugins_HEADERS = $(headers)
|
|
@ -0,0 +1,8 @@
|
|||
# 3rd Party libraries to be built and installed along with gtsam
|
||||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS = Eigen
|
||||
|
||||
# And the corresponding libraries produced
|
||||
# TODO add sublibs when something in 3rdparty actually needs compilation
|
||||
# SUBLIBS =
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# All the sub-directories that need to be built
|
||||
SUBDIRS = base geometry inference linear nonlinear slam
|
||||
SUBDIRS = base geometry inference linear nonlinear slam 3rdparty
|
||||
|
||||
# And the corresponding libraries produced
|
||||
SUBLIBS = base/libbase.la geometry/libgeometry.la inference/libinference.la \
|
||||
|
@ -12,7 +12,3 @@ libgtsam_la_SOURCES =
|
|||
nodist_EXTRA_libgtsam_la_SOURCES = dummy.cxx
|
||||
libgtsam_la_LIBADD = $(SUBLIBS) -L$(CCOLAMDLib) $(BOOST_LDFLAGS) -lccolamd
|
||||
libgtsam_la_LDFLAGS = -no-undefined -version-info 0:0:0
|
||||
|
||||
if USE_ACCELERATE_MACOS
|
||||
libgtsam_la_LDFLAGS += -Wl,/System/Library/Frameworks/Accelerate.framework/Accelerate
|
||||
endif
|
||||
|
|
|
@ -19,149 +19,146 @@
|
|||
|
||||
#include <gtsam/base/timing.h>
|
||||
#include <gtsam/base/DenseQRUtil.h>
|
||||
#include <boost/numeric/ublas/matrix.hpp>
|
||||
#include <boost/numeric/ublas/matrix_proxy.hpp>
|
||||
#include <boost/numeric/ublas/triangular.hpp>
|
||||
|
||||
#include <string.h> // for memcpy and memset
|
||||
|
||||
using namespace std;
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
//namespace ublas = boost::numeric::ublas;
|
||||
|
||||
#ifdef GT_USE_LAPACK
|
||||
namespace gtsam {
|
||||
|
||||
/* ************************************************************************* */
|
||||
int* MakeStairs(Matrix& A) {
|
||||
|
||||
const int m = A.size1();
|
||||
const int n = A.size2();
|
||||
int* Stair = new int[n];
|
||||
|
||||
// record the starting pointer of each row
|
||||
double* a[m];
|
||||
list<int> remained;
|
||||
a[0] = A.data().begin();
|
||||
for(int i=0; i<m-1; i++) {
|
||||
a[i+1] = a[i] + n;
|
||||
remained.push_back(i);
|
||||
}
|
||||
remained.push_back(m-1);
|
||||
|
||||
// reorder the rows
|
||||
int j;
|
||||
vector<int> sorted;
|
||||
list<int>::iterator itRemained;
|
||||
for(j = 0; j < n; ) {
|
||||
// remove the non-zero rows in the current column
|
||||
for(itRemained = remained.begin(); itRemained!=remained.end(); ) {
|
||||
if (*(a[*itRemained]) != 0) {
|
||||
sorted.push_back(*itRemained);
|
||||
itRemained = remained.erase(itRemained);
|
||||
} else {
|
||||
a[*itRemained]++;
|
||||
itRemained ++;
|
||||
}
|
||||
}
|
||||
|
||||
// record the stair number
|
||||
Stair[j++] = m - remained.size();
|
||||
|
||||
if(remained.empty()) break;
|
||||
}
|
||||
|
||||
// all the remained columns have maximum stair
|
||||
for (; j<n; j++)
|
||||
Stair[j] = m;
|
||||
|
||||
// copy the new row
|
||||
Matrix A_new = zeros(m,n);
|
||||
int offset[m];
|
||||
offset[0] = 0;
|
||||
for(int i=1; i<m; i++)
|
||||
offset[i] = offset[i-1] +n;
|
||||
vector<int>::const_iterator itSorted;
|
||||
double* ptr1 = A.data().begin();
|
||||
double* ptr2 = A_new.data().begin();
|
||||
int row = 0, sizeOfRow = n * sizeof(double);
|
||||
for(itSorted=sorted.begin(); itSorted!=sorted.end(); itSorted++, row++)
|
||||
memcpy(ptr2+offset[row], ptr1+offset[*itSorted], sizeOfRow);
|
||||
|
||||
A = A_new;
|
||||
|
||||
return Stair;
|
||||
}
|
||||
|
||||
void printColumnMajor(const double* a, const int m, const int n) {
|
||||
for(int i=0; i<m; i++) {
|
||||
for(int j=0; j<n; j++)
|
||||
cout << a[j*m+i] << "\t";
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void householder_denseqr(Matrix &A, int* Stair) {
|
||||
|
||||
tic("householder_denseqr");
|
||||
|
||||
int m = A.size1();
|
||||
int n = A.size2();
|
||||
|
||||
bool allocedStair = false;
|
||||
if (Stair == NULL) {
|
||||
allocedStair = true;
|
||||
Stair = new int[n];
|
||||
for(int j=0; j<n; j++)
|
||||
Stair[j] = m;
|
||||
}
|
||||
|
||||
tic("householder_denseqr: row->col");
|
||||
// convert from row major to column major
|
||||
ublas::matrix<double, ublas::column_major> Acolwise(A);
|
||||
double *a = Acolwise.data().begin();
|
||||
toc("householder_denseqr: row->col");
|
||||
|
||||
tic("householder_denseqr: denseqr_front");
|
||||
int npiv = min(m,n);
|
||||
int b = min(min(m,n),32);
|
||||
double W[b*(n+b)];
|
||||
DenseQR(m, n, npiv, a, Stair, W);
|
||||
toc("householder_denseqr: denseqr_front");
|
||||
|
||||
tic("householder_denseqr: col->row");
|
||||
int k0 = 0;
|
||||
int j0;
|
||||
int k;
|
||||
memset(A.data().begin(), 0, m*n*sizeof(double));
|
||||
for(int j=0; j<n; j++, k0+=m) {
|
||||
k = k0;
|
||||
j0 = min(j+1,m);
|
||||
for(int i=0; i<j0; i++, k++)
|
||||
A(i,j) = a[k];
|
||||
}
|
||||
|
||||
toc("householder_denseqr: col->row");
|
||||
|
||||
|
||||
if(allocedStair) delete[] Stair;
|
||||
|
||||
toc("householder_denseqr");
|
||||
}
|
||||
|
||||
void householder_denseqr_colmajor(ublas::matrix<double, ublas::column_major>& A, int *Stair) {
|
||||
int m = A.size1();
|
||||
int n = A.size2();
|
||||
|
||||
assert(Stair != NULL);
|
||||
|
||||
tic(1, "householder_denseqr");
|
||||
int npiv = min(m,n);
|
||||
int b = min(min(m,n),32);
|
||||
double W[b*(n+b)];
|
||||
DenseQR(m, n, npiv, A.data().begin(), Stair, W);
|
||||
toc(1, "householder_denseqr");
|
||||
}
|
||||
|
||||
} // namespace gtsam
|
||||
#endif
|
||||
//#ifdef GT_USE_LAPACK
|
||||
//namespace gtsam {
|
||||
//
|
||||
// /* ************************************************************************* */
|
||||
// int* MakeStairs(Matrix& A) {
|
||||
//
|
||||
// const int m = A.rows();
|
||||
// const int n = A.cols();
|
||||
// int* Stair = new int[n];
|
||||
//
|
||||
// // record the starting pointer of each row
|
||||
// double* a[m];
|
||||
// list<int> remained;
|
||||
// a[0] = A.data();
|
||||
// for(int i=0; i<m-1; i++) {
|
||||
// a[i+1] = a[i] + n;
|
||||
// remained.push_back(i);
|
||||
// }
|
||||
// remained.push_back(m-1);
|
||||
//
|
||||
// // reorder the rows
|
||||
// int j;
|
||||
// vector<int> sorted;
|
||||
// list<int>::iterator itRemained;
|
||||
// for(j = 0; j < n; ) {
|
||||
// // remove the non-zero rows in the current column
|
||||
// for(itRemained = remained.begin(); itRemained!=remained.end(); ) {
|
||||
// if (*(a[*itRemained]) != 0) {
|
||||
// sorted.push_back(*itRemained);
|
||||
// itRemained = remained.erase(itRemained);
|
||||
// } else {
|
||||
// a[*itRemained]++;
|
||||
// itRemained ++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // record the stair number
|
||||
// Stair[j++] = m - remained.size();
|
||||
//
|
||||
// if(remained.empty()) break;
|
||||
// }
|
||||
//
|
||||
// // all the remained columns have maximum stair
|
||||
// for (; j<n; j++)
|
||||
// Stair[j] = m;
|
||||
//
|
||||
// // copy the new row
|
||||
// Matrix A_new = zeros(m,n);
|
||||
// int offset[m];
|
||||
// offset[0] = 0;
|
||||
// for(int i=1; i<m; i++)
|
||||
// offset[i] = offset[i-1] +n;
|
||||
// vector<int>::const_iterator itSorted;
|
||||
// double* ptr1 = A.data();
|
||||
// double* ptr2 = A_new.data();
|
||||
// int row = 0, sizeOfRow = n * sizeof(double);
|
||||
// for(itSorted=sorted.begin(); itSorted!=sorted.end(); itSorted++, row++)
|
||||
// memcpy(ptr2+offset[row], ptr1+offset[*itSorted], sizeOfRow);
|
||||
//
|
||||
// A = A_new;
|
||||
//
|
||||
// return Stair;
|
||||
// }
|
||||
//
|
||||
// void printColumnMajor(const double* a, const int m, const int n) {
|
||||
// for(int i=0; i<m; i++) {
|
||||
// for(int j=0; j<n; j++)
|
||||
// cout << a[j*m+i] << "\t";
|
||||
// cout << endl;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /* ************************************************************************* */
|
||||
// void householder_denseqr(Matrix &A, int* Stair) {
|
||||
//
|
||||
// tic("householder_denseqr");
|
||||
//
|
||||
// int m = A.rows();
|
||||
// int n = A.cols();
|
||||
//
|
||||
// bool allocedStair = false;
|
||||
// if (Stair == NULL) {
|
||||
// allocedStair = true;
|
||||
// Stair = new int[n];
|
||||
// for(int j=0; j<n; j++)
|
||||
// Stair[j] = m;
|
||||
// }
|
||||
//
|
||||
// tic("householder_denseqr: row->col");
|
||||
// // convert from row major to column major
|
||||
// MatrixColMajor Acolwise(A);
|
||||
// double *a = Acolwise.data();
|
||||
// toc("householder_denseqr: row->col");
|
||||
//
|
||||
// tic("householder_denseqr: denseqr_front");
|
||||
// int npiv = min(m,n);
|
||||
// int b = min(min(m,n),32);
|
||||
// double W[b*(n+b)];
|
||||
// DenseQR(m, n, npiv, a, Stair, W);
|
||||
// toc("householder_denseqr: denseqr_front");
|
||||
//
|
||||
// tic("householder_denseqr: col->row");
|
||||
// int k0 = 0;
|
||||
// int j0;
|
||||
// int k;
|
||||
// memset(A.data(), 0, m*n*sizeof(double));
|
||||
// for(int j=0; j<n; j++, k0+=m) {
|
||||
// k = k0;
|
||||
// j0 = min(j+1,m);
|
||||
// for(int i=0; i<j0; i++, k++)
|
||||
// A(i,j) = a[k];
|
||||
// }
|
||||
//
|
||||
// toc("householder_denseqr: col->row");
|
||||
//
|
||||
//
|
||||
// if(allocedStair) delete[] Stair;
|
||||
//
|
||||
// toc("householder_denseqr");
|
||||
// }
|
||||
//
|
||||
// void householder_denseqr_colmajor(MatrixColMajor& A, int *Stair) {
|
||||
// int m = A.rows();
|
||||
// int n = A.cols();
|
||||
//
|
||||
// assert(Stair != NULL);
|
||||
//
|
||||
// tic(1, "householder_denseqr");
|
||||
// int npiv = min(m,n);
|
||||
// int b = min(min(m,n),32);
|
||||
// double W[b*(n+b)];
|
||||
// DenseQR(m, n, npiv, A.data(), Stair, W);
|
||||
// toc(1, "householder_denseqr");
|
||||
// }
|
||||
//
|
||||
//} // namespace gtsam
|
||||
//#endif
|
||||
|
|
|
@ -21,17 +21,17 @@
|
|||
|
||||
#include <gtsam/base/Matrix.h>
|
||||
|
||||
#ifdef GT_USE_LAPACK
|
||||
#include <gtsam/base/DenseQR.h>
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
/** make stairs and speed up householder_denseqr. Stair is defined as the row index of where zero entries start in each column */
|
||||
int* MakeStairs(Matrix &A);
|
||||
|
||||
/** Householder tranformation, zeros below diagonal */
|
||||
void householder_denseqr(Matrix &A, int* Stair = NULL);
|
||||
|
||||
void householder_denseqr_colmajor(boost::numeric::ublas::matrix<double, boost::numeric::ublas::column_major>& A, int *Stair);
|
||||
}
|
||||
#endif
|
||||
//#ifdef GT_USE_LAPACK
|
||||
//#include <gtsam/base/DenseQR.h>
|
||||
//
|
||||
//namespace gtsam {
|
||||
//
|
||||
// /** make stairs and speed up householder_denseqr. Stair is defined as the row index of where zero entries start in each column */
|
||||
// int* MakeStairs(Matrix &A);
|
||||
//
|
||||
// /** Householder tranformation, zeros below diagonal */
|
||||
// void householder_denseqr(Matrix &A, int* Stair = NULL);
|
||||
//
|
||||
// void householder_denseqr_colmajor(MatrixColMajor& A, int *Stair);
|
||||
//}
|
||||
//#endif
|
||||
|
|
|
@ -28,10 +28,10 @@ namespace gtsam {
|
|||
* size checking.
|
||||
*/
|
||||
template<size_t N>
|
||||
class FixedVector : public boost::numeric::ublas::bounded_vector<double, N> ,
|
||||
class FixedVector : public Eigen::Matrix<double, N, 1>,
|
||||
public Testable<FixedVector<N> > {
|
||||
public:
|
||||
typedef boost::numeric::ublas::bounded_vector<double, N> Base;
|
||||
typedef Eigen::Matrix<double, N, 1> Base;
|
||||
|
||||
/** default constructor */
|
||||
FixedVector() {}
|
||||
|
@ -44,7 +44,7 @@ public:
|
|||
|
||||
/** Initialize with a C-style array */
|
||||
FixedVector(const double* values) {
|
||||
std::copy(values, values+N, this->data().begin());
|
||||
std::copy(values, values+N, this->data());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,10 +69,11 @@ public:
|
|||
* @param constant value
|
||||
*/
|
||||
inline static FixedVector repeat(double value) {
|
||||
FixedVector v;
|
||||
for (size_t i=0; i<N; ++i)
|
||||
v(i) = value;
|
||||
return v;
|
||||
return FixedVector(Base::Constant(value));
|
||||
// FixedVector v;
|
||||
// for (size_t i=0; i<N; ++i)
|
||||
// v(i) = value;
|
||||
// return v;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,9 +84,10 @@ public:
|
|||
* @return delta vector
|
||||
*/
|
||||
inline static FixedVector delta(size_t i, double value) {
|
||||
FixedVector v = zero();
|
||||
v(i) = value;
|
||||
return v;
|
||||
return FixedVector(Base::Unit(i) * value);
|
||||
// FixedVector v = zero();
|
||||
// v(i) = value;
|
||||
// return v;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,17 +96,17 @@ public:
|
|||
* @param index of the one
|
||||
* @return basis vector
|
||||
*/
|
||||
inline static FixedVector basis(size_t i) { return delta(i, 1.0); }
|
||||
inline static FixedVector basis(size_t i) { return FixedVector(Base::Unit(i)); }
|
||||
|
||||
/**
|
||||
* Create zero vector
|
||||
*/
|
||||
inline static FixedVector zero() { return repeat(0.0);}
|
||||
inline static FixedVector zero() { return FixedVector(Base::Zero());}
|
||||
|
||||
/**
|
||||
* Create vector initialized to ones
|
||||
*/
|
||||
inline static FixedVector ones() { return repeat(1.0);}
|
||||
inline static FixedVector ones() { return FixedVector(FixedVector::Ones());}
|
||||
|
||||
static size_t dim() { return Base::max_size; }
|
||||
|
||||
|
|
|
@ -23,83 +23,83 @@
|
|||
|
||||
namespace gtsam {
|
||||
|
||||
/**
|
||||
* LieVector is a wrapper around vector to allow it to be a Lie type
|
||||
*/
|
||||
struct LieVector : public Vector, public Lie<LieVector>, Testable<LieVector> {
|
||||
|
||||
/** default constructor - should be unnecessary */
|
||||
LieVector() {}
|
||||
|
||||
/** initialize from a normal vector */
|
||||
LieVector(const Vector& v) : Vector(v) {}
|
||||
|
||||
/** wrap a double */
|
||||
LieVector(double d) : Vector(Vector_(1, d)) {}
|
||||
|
||||
/** constructor with size and initial data, row order ! */
|
||||
LieVector(size_t m, const double* const data);
|
||||
|
||||
/** Specify arguments directly, as in Vector_() - always force these to be doubles */
|
||||
LieVector(size_t m, ...);
|
||||
|
||||
/** get the underlying vector */
|
||||
inline Vector vector() const {
|
||||
return static_cast<Vector>(*this);
|
||||
}
|
||||
|
||||
/** print @param s optional string naming the object */
|
||||
inline void print(const std::string& name="") const {
|
||||
gtsam::print(vector(), name);
|
||||
}
|
||||
|
||||
/** equality up to tolerance */
|
||||
inline bool equals(const LieVector& expected, double tol=1e-5) const {
|
||||
return gtsam::equal(vector(), expected.vector(), tol);
|
||||
}
|
||||
|
||||
/**
|
||||
* LieVector is a wrapper around vector to allow it to be a Lie type
|
||||
* Returns dimensionality of the tangent space
|
||||
*/
|
||||
struct LieVector : public Vector, public Lie<LieVector>, Testable<LieVector> {
|
||||
inline size_t dim() const { return this->size(); }
|
||||
|
||||
/** default constructor - should be unnecessary */
|
||||
LieVector() {}
|
||||
/**
|
||||
* Returns Exponential map update of T
|
||||
* Default implementation calls global binary function
|
||||
*/
|
||||
inline LieVector expmap(const Vector& v) const { return LieVector(vector() + v); }
|
||||
|
||||
/** initialize from a normal vector */
|
||||
LieVector(const Vector& v) : Vector(v) {}
|
||||
/** expmap around identity */
|
||||
static inline LieVector Expmap(const Vector& v) { return LieVector(v); }
|
||||
|
||||
/** wrap a double */
|
||||
LieVector(double d) : Vector(Vector_(1, d)) {}
|
||||
/**
|
||||
* Returns Log map
|
||||
* Default Implementation calls global binary function
|
||||
*/
|
||||
inline Vector logmap(const LieVector& lp) const {
|
||||
return lp.vector() - vector();
|
||||
}
|
||||
|
||||
/** constructor with size and initial data, row order ! */
|
||||
LieVector(size_t m, const double* const data);
|
||||
/** Logmap around identity - just returns with default cast back */
|
||||
static inline Vector Logmap(const LieVector& p) { return p; }
|
||||
|
||||
/** Specify arguments directly, as in Vector_() - always force these to be doubles */
|
||||
LieVector(size_t m, ...);
|
||||
/** compose with another object */
|
||||
inline LieVector compose(const LieVector& p) const {
|
||||
return LieVector(vector() + p);
|
||||
}
|
||||
|
||||
/** get the underlying vector */
|
||||
inline Vector vector() const {
|
||||
return static_cast<Vector>(*this);
|
||||
}
|
||||
/** between operation */
|
||||
inline LieVector between(const LieVector& l2,
|
||||
boost::optional<Matrix&> H1=boost::none,
|
||||
boost::optional<Matrix&> H2=boost::none) const {
|
||||
if(H1) *H1 = -eye(dim());
|
||||
if(H2) *H2 = eye(l2.dim());
|
||||
return LieVector(l2.vector() - vector());
|
||||
}
|
||||
|
||||
/** print @param s optional string naming the object */
|
||||
inline void print(const std::string& name="") const {
|
||||
gtsam::print(vector(), name);
|
||||
}
|
||||
|
||||
/** equality up to tolerance */
|
||||
inline bool equals(const LieVector& expected, double tol=1e-5) const {
|
||||
return gtsam::equal(vector(), expected.vector(), tol);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns dimensionality of the tangent space
|
||||
*/
|
||||
inline size_t dim() const { return this->size(); }
|
||||
|
||||
/**
|
||||
* Returns Exponential map update of T
|
||||
* Default implementation calls global binary function
|
||||
*/
|
||||
inline LieVector expmap(const Vector& v) const { return LieVector(vector() + v); }
|
||||
|
||||
/** expmap around identity */
|
||||
static inline LieVector Expmap(const Vector& v) { return LieVector(v); }
|
||||
|
||||
/**
|
||||
* Returns Log map
|
||||
* Default Implementation calls global binary function
|
||||
*/
|
||||
inline Vector logmap(const LieVector& lp) const {
|
||||
return lp.vector() - vector();
|
||||
}
|
||||
|
||||
/** Logmap around identity - just returns with default cast back */
|
||||
static inline Vector Logmap(const LieVector& p) { return p; }
|
||||
|
||||
/** compose with another object */
|
||||
inline LieVector compose(const LieVector& p) const {
|
||||
return LieVector(vector() + p);
|
||||
}
|
||||
|
||||
/** between operation */
|
||||
inline LieVector between(const LieVector& l2,
|
||||
boost::optional<Matrix&> H1=boost::none,
|
||||
boost::optional<Matrix&> H2=boost::none) const {
|
||||
if(H1) *H1 = -eye(dim());
|
||||
if(H2) *H2 = eye(l2.dim());
|
||||
return LieVector(l2.vector() - vector());
|
||||
}
|
||||
|
||||
/** invert the object and yield a new one */
|
||||
inline LieVector inverse() const {
|
||||
return LieVector(-1.0 * vector());
|
||||
}
|
||||
};
|
||||
/** invert the object and yield a new one */
|
||||
inline LieVector inverse() const {
|
||||
return LieVector(-1.0 * vector());
|
||||
}
|
||||
};
|
||||
} // \namespace gtsam
|
||||
|
|
|
@ -13,15 +13,15 @@ check_PROGRAMS =
|
|||
|
||||
# base Math
|
||||
|
||||
headers += FixedVector.h types.h blockMatrices.h Matrix-inl.h lapack.h
|
||||
sources += Vector.cpp Matrix.cpp cholesky.cpp
|
||||
check_PROGRAMS += tests/testFixedVector tests/testVector tests/testMatrix tests/testCholesky
|
||||
headers += FixedVector.h types.h blockMatrices.h Matrix-inl.h
|
||||
sources += Vector.cpp Matrix.cpp
|
||||
sources += cholesky.cpp
|
||||
check_PROGRAMS += tests/testFixedVector tests/testVector tests/testMatrix tests/testBlockMatrices
|
||||
check_PROGRAMS += tests/testCholesky
|
||||
check_PROGRAMS += tests/testNumericalDerivative
|
||||
|
||||
if USE_LAPACK
|
||||
sources += DenseQR.cpp DenseQRUtil.cpp
|
||||
check_PROGRAMS += tests/testDenseQRUtil
|
||||
endif
|
||||
#sources += DenseQR.cpp DenseQRUtil.cpp
|
||||
#check_PROGRAMS += tests/testDenseQRUtil
|
||||
|
||||
# Testing
|
||||
headers += Testable.h TestableAssertions.h numericalDerivative.h
|
||||
|
@ -39,7 +39,8 @@ sources += DSFVector.cpp
|
|||
check_PROGRAMS += tests/testBTree tests/testDSF tests/testDSFVector
|
||||
|
||||
# Timing tests
|
||||
noinst_PROGRAMS = tests/timeMatrix tests/timeublas tests/timeVirtual tests/timeTest
|
||||
noinst_PROGRAMS = tests/timeMatrix tests/timeVirtual tests/timeTest
|
||||
#noinst_PROGRAMS += tests/timeublas
|
||||
|
||||
#----------------------------------------------------------------------------------------------------
|
||||
# Create a libtool library that is not installed
|
||||
|
@ -54,18 +55,9 @@ libbase_la_SOURCES = $(sources)
|
|||
|
||||
AM_CPPFLAGS =
|
||||
|
||||
# On Mac, we compile using the BLAS/LAPACK headers in the Accelerate framework
|
||||
if USE_ACCELERATE_MACOS
|
||||
AM_CPPFLAGS += -I/System/Library/Frameworks/vecLib.framework/Headers
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS += $(BOOST_CPPFLAGS) -I$(CCOLAMDInc) -I$(top_srcdir)
|
||||
AM_LDFLAGS = $(BOOST_LDFLAGS)
|
||||
|
||||
if USE_BLAS
|
||||
AM_CPPFLAGS += -DGT_USE_CBLAS
|
||||
endif
|
||||
|
||||
#----------------------------------------------------------------------------------------------------
|
||||
# rules to build local programs
|
||||
#----------------------------------------------------------------------------------------------------
|
||||
|
@ -74,22 +66,6 @@ AM_DEFAULT_SOURCE_EXT = .cpp
|
|||
AM_LDFLAGS += $(boost_serialization) -L$(CCOLAMDLib) -lccolamd
|
||||
LDADD = libbase.la ../../CppUnitLite/libCppUnitLite.a
|
||||
|
||||
if USE_BLAS_LINUX
|
||||
AM_LDFLAGS += -lcblas -latlas
|
||||
endif
|
||||
|
||||
if USE_LAPACK
|
||||
AM_CPPFLAGS += -DGT_USE_LAPACK
|
||||
endif
|
||||
|
||||
if USE_LAPACK_LINUX
|
||||
AM_LDFLAGS += -llapack
|
||||
endif
|
||||
|
||||
if USE_ACCELERATE_MACOS
|
||||
AM_LDFLAGS += -Wl,/System/Library/Frameworks/Accelerate.framework/Accelerate
|
||||
endif
|
||||
|
||||
# rule to run an executable
|
||||
%.run: % $(LDADD)
|
||||
./$^
|
||||
|
|
|
@ -26,84 +26,82 @@ namespace gtsam {
|
|||
|
||||
using namespace std;
|
||||
|
||||
/* ************************************************************************* */
|
||||
/**
|
||||
* backSubstitute U*x=b
|
||||
* @param U an upper triangular matrix
|
||||
* @param b an RHS vector
|
||||
* @return the solution x of U*x=b
|
||||
*/
|
||||
template<class MATRIX, class VECTOR>
|
||||
Vector backSubstituteUpper(const boost::numeric::ublas::matrix_expression<MATRIX>& _U,
|
||||
const boost::numeric::ublas::vector_expression<VECTOR>& _b, bool unit=false) {
|
||||
const MATRIX& U(*static_cast<const MATRIX*>(&_U));
|
||||
const VECTOR& b(*static_cast<const VECTOR*>(&_b));
|
||||
size_t n = U.size2();
|
||||
#ifndef NDEBUG
|
||||
size_t m = U.size1();
|
||||
if (m!=n)
|
||||
throw invalid_argument("backSubstituteUpper: U must be square");
|
||||
#endif
|
||||
|
||||
Vector result(n);
|
||||
for (size_t i = n; i > 0; i--) {
|
||||
double zi = b(i-1);
|
||||
for (size_t j = i+1; j <= n; j++)
|
||||
zi -= U(i-1,j-1) * result(j-1);
|
||||
#ifndef NDEBUG
|
||||
if(!unit && fabs(U(i-1,i-1)) <= numeric_limits<double>::epsilon()) {
|
||||
stringstream ss;
|
||||
ss << "backSubstituteUpper: U is singular,\n";
|
||||
print(U, "U: ", ss);
|
||||
throw invalid_argument(ss.str());
|
||||
}
|
||||
#endif
|
||||
if (!unit) zi /= U(i-1,i-1);
|
||||
result(i-1) = zi;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
/**
|
||||
* backSubstitute x'*U=b'
|
||||
* @param U an upper triangular matrix
|
||||
* @param b an RHS vector
|
||||
* @param unit, set true if unit triangular
|
||||
* @return the solution x of x'*U=b'
|
||||
* TODO: use boost
|
||||
*/
|
||||
template<class VECTOR, class MATRIX>
|
||||
Vector backSubstituteUpper(const boost::numeric::ublas::vector_expression<VECTOR>& _b,
|
||||
const boost::numeric::ublas::matrix_expression<MATRIX>& _U, bool unit=false) {
|
||||
const VECTOR& b(*static_cast<const VECTOR*>(&_b));
|
||||
const MATRIX& U(*static_cast<const MATRIX*>(&_U));
|
||||
size_t n = U.size2();
|
||||
#ifndef NDEBUG
|
||||
size_t m = U.size1();
|
||||
if (m!=n)
|
||||
throw invalid_argument("backSubstituteUpper: U must be square");
|
||||
#endif
|
||||
|
||||
Vector result(n);
|
||||
for (size_t i = 1; i <= n; i++) {
|
||||
double zi = b(i-1);
|
||||
for (size_t j = 1; j < i; j++)
|
||||
zi -= U(j-1,i-1) * result(j-1);
|
||||
#ifndef NDEBUG
|
||||
if(!unit && fabs(U(i-1,i-1)) <= numeric_limits<double>::epsilon()) {
|
||||
stringstream ss;
|
||||
ss << "backSubstituteUpper: U is singular,\n";
|
||||
print(U, "U: ", ss);
|
||||
throw invalid_argument(ss.str());
|
||||
}
|
||||
#endif
|
||||
if (!unit) zi /= U(i-1,i-1);
|
||||
result(i-1) = zi;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
///* ************************************************************************* */
|
||||
///**
|
||||
// * backSubstitute U*x=b
|
||||
// * @param U an upper triangular matrix
|
||||
// * @param b an RHS vector
|
||||
// * @return the solution x of U*x=b
|
||||
// */
|
||||
//template<class MATRIX, class VECTOR>
|
||||
//Vector backSubstituteUpper(const MATRIX& U, const VECTOR& b, bool unit=false) {
|
||||
//// const MATRIX& U(*static_cast<const MATRIX*>(&_U));
|
||||
//// const VECTOR& b(*static_cast<const VECTOR*>(&_b));
|
||||
// size_t n = U.cols();
|
||||
//#ifndef NDEBUG
|
||||
// size_t m = U.rows();
|
||||
// if (m!=n)
|
||||
// throw invalid_argument("backSubstituteUpper: U must be square");
|
||||
//#endif
|
||||
//
|
||||
// Vector result(n);
|
||||
// for (size_t i = n; i > 0; i--) {
|
||||
// double zi = b(i-1);
|
||||
// for (size_t j = i+1; j <= n; j++)
|
||||
// zi -= U(i-1,j-1) * result(j-1);
|
||||
//#ifndef NDEBUG
|
||||
// if(!unit && fabs(U(i-1,i-1)) <= numeric_limits<double>::epsilon()) {
|
||||
// stringstream ss;
|
||||
// ss << "backSubstituteUpper: U is singular,\n";
|
||||
// print(U, "U: ", ss);
|
||||
// throw invalid_argument(ss.str());
|
||||
// }
|
||||
//#endif
|
||||
// if (!unit) zi /= U(i-1,i-1);
|
||||
// result(i-1) = zi;
|
||||
// }
|
||||
//
|
||||
// return result;
|
||||
//}
|
||||
//
|
||||
///* ************************************************************************* */
|
||||
///**
|
||||
// * backSubstitute x'*U=b'
|
||||
// * @param U an upper triangular matrix
|
||||
// * @param b an RHS vector
|
||||
// * @param unit, set true if unit triangular
|
||||
// * @return the solution x of x'*U=b'
|
||||
// * TODO: use boost
|
||||
// */
|
||||
//template<class VECTOR, class MATRIX>
|
||||
//Vector backSubstituteUpper(const VECTOR& b, const MATRIX& U, bool unit=false) {
|
||||
//// const VECTOR& b(*static_cast<const VECTOR*>(&_b));
|
||||
//// const MATRIX& U(*static_cast<const MATRIX*>(&_U));
|
||||
// size_t n = U.cols();
|
||||
//#ifndef NDEBUG
|
||||
// size_t m = U.rows();
|
||||
// if (m!=n)
|
||||
// throw invalid_argument("backSubstituteUpper: U must be square");
|
||||
//#endif
|
||||
//
|
||||
// Vector result(n);
|
||||
// for (size_t i = 1; i <= n; i++) {
|
||||
// double zi = b(i-1);
|
||||
// for (size_t j = 1; j < i; j++)
|
||||
// zi -= U(j-1,i-1) * result(j-1);
|
||||
//#ifndef NDEBUG
|
||||
// if(!unit && fabs(U(i-1,i-1)) <= numeric_limits<double>::epsilon()) {
|
||||
// stringstream ss;
|
||||
// ss << "backSubstituteUpper: U is singular,\n";
|
||||
// print(U, "U: ", ss);
|
||||
// throw invalid_argument(ss.str());
|
||||
// }
|
||||
//#endif
|
||||
// if (!unit) zi /= U(i-1,i-1);
|
||||
// result(i-1) = zi;
|
||||
// }
|
||||
//
|
||||
// return result;
|
||||
//}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,10 +11,11 @@
|
|||
|
||||
/**
|
||||
* @file Matrix.h
|
||||
* @brief typedef and functions to augment Boost's ublas::matrix<double>
|
||||
* @brief typedef and functions to augment Eigen's MatrixXd
|
||||
* @author Christian Potthast
|
||||
* @author Kai Ni
|
||||
* @author Frank Dellaert
|
||||
* @author Alex Cunningham
|
||||
*/
|
||||
|
||||
// \callgraph
|
||||
|
@ -23,20 +24,28 @@
|
|||
|
||||
#include <list>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/numeric/ublas/matrix.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <gtsam/3rdparty/Eigen/QR>
|
||||
#include <gtsam/base/Vector.h>
|
||||
|
||||
/**
|
||||
* Vector is a *global* typedef
|
||||
* Matrix is a *global* typedef
|
||||
* wrap-matlab does this typedef as well
|
||||
* we use the default < double,row_major,unbounded_array<double> >
|
||||
*/
|
||||
|
||||
#if ! defined (MEX_H)
|
||||
typedef boost::numeric::ublas::matrix<double> Matrix;
|
||||
typedef boost::numeric::ublas::matrix<double, boost::numeric::ublas::column_major> MatrixColMajor;
|
||||
#endif
|
||||
// FIXME: replace to handle matlab wrapper
|
||||
//#if ! defined (MEX_H)
|
||||
//typedef boost::numeric::ublas::matrix<double> Matrix;
|
||||
//typedef boost::numeric::ublas::matrix<double, boost::numeric::ublas::column_major> MatrixColMajor;
|
||||
//#endif
|
||||
|
||||
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> Matrix;
|
||||
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor> MatrixColMajor;
|
||||
|
||||
// Matrix expressions for accessing parts of matrices
|
||||
typedef Eigen::Block<Matrix> SubMatrix;
|
||||
typedef Eigen::Block<const Matrix> ConstSubMatrix;
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
|
@ -72,7 +81,23 @@ Matrix diag(const Vector& v);
|
|||
/**
|
||||
* equals with an tolerance
|
||||
*/
|
||||
bool equal_with_abs_tol(const Matrix& A, const Matrix& B, double tol = 1e-9);
|
||||
template <class MATRIX>
|
||||
bool equal_with_abs_tol(const Eigen::DenseBase<MATRIX>& A, const Eigen::DenseBase<MATRIX>& B, double tol = 1e-9) {
|
||||
|
||||
const size_t n1 = A.cols(), m1 = A.rows();
|
||||
const size_t n2 = B.cols(), m2 = B.rows();
|
||||
|
||||
if(m1!=m2 || n1!=n2) return false;
|
||||
|
||||
for(size_t i=0; i<m1; i++)
|
||||
for(size_t j=0; j<n1; j++) {
|
||||
if(std::isnan(A(i,j)) xor std::isnan(B(i,j)))
|
||||
return false;
|
||||
else if(fabs(A(i,j) - B(i,j)) > tol)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* equality is just equal_with_abs_tol 1e-9
|
||||
|
@ -91,7 +116,9 @@ inline bool operator!=(const Matrix& A, const Matrix& B) {
|
|||
/**
|
||||
* equals with an tolerance, prints out message if unequal
|
||||
*/
|
||||
// FIXME: make better use of templates to test these properly
|
||||
bool assert_equal(const Matrix& A, const Matrix& B, double tol = 1e-9);
|
||||
bool assert_equal(const MatrixColMajor& A, const MatrixColMajor& B, double tol = 1e-9);
|
||||
|
||||
/**
|
||||
* equals with an tolerance, prints out message if unequal
|
||||
|
@ -108,11 +135,6 @@ bool linear_independent(const Matrix& A, const Matrix& B, double tol = 1e-9);
|
|||
*/
|
||||
bool linear_dependent(const Matrix& A, const Matrix& B, double tol = 1e-9);
|
||||
|
||||
/**
|
||||
* overload * for matrix-vector multiplication (as BOOST does not)
|
||||
*/
|
||||
inline Vector operator*(const Matrix& A, const Vector & v) { return prod(A,v);}
|
||||
|
||||
/**
|
||||
* BLAS Level-2 style e <- e + alpha*A*x
|
||||
*/
|
||||
|
@ -144,15 +166,12 @@ void transposeMultiplyAdd(const Matrix& A, const Vector& e, Vector& x);
|
|||
*/
|
||||
void transposeMultiplyAdd(double alpha, const Matrix& A, const Vector& e, SubVector x);
|
||||
|
||||
/**
|
||||
* overload * for vector*matrix multiplication (as BOOST does not)
|
||||
*/
|
||||
inline Vector operator*(const Vector & v, const Matrix& A) { return prod(v,A);}
|
||||
|
||||
/**
|
||||
* overload * for matrix multiplication (as BOOST does not)
|
||||
*/
|
||||
inline Matrix operator*(const Matrix& A, const Matrix& B) { return prod(A,B);}
|
||||
/** products using old-style format to improve compatibility */
|
||||
template<class MATRIX>
|
||||
inline MATRIX prod(const MATRIX& A, const MATRIX&B) {
|
||||
MATRIX result = A * B;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert to column vector, column order !!!
|
||||
|
@ -163,6 +182,7 @@ Vector Vector_(const Matrix& A);
|
|||
* print a matrix
|
||||
*/
|
||||
void print(const Matrix& A, const std::string& s = "", std::ostream& stream = std::cout);
|
||||
void print(const MatrixColMajor& A, const std::string& s = "", std::ostream& stream = std::cout);
|
||||
|
||||
/**
|
||||
* save a matrix to file, which can be loaded by matlab
|
||||
|
@ -178,7 +198,11 @@ void save(const Matrix& A, const std::string &s, const std::string& filename);
|
|||
* @param j2 last col index + 1
|
||||
* @return submatrix A(i1:i2-1,j1:j2-1)
|
||||
*/
|
||||
Matrix sub(const Matrix& A, size_t i1, size_t i2, size_t j1, size_t j2);
|
||||
template<class MATRIX>
|
||||
Eigen::Block<const MATRIX> sub(const MATRIX& A, size_t i1, size_t i2, size_t j1, size_t j2) {
|
||||
size_t m=i2-i1, n=j2-j1;
|
||||
return A.block(i1,j1,m,n);
|
||||
}
|
||||
|
||||
/**
|
||||
* insert a submatrix IN PLACE at a specified location in a larger matrix
|
||||
|
@ -191,13 +215,26 @@ Matrix sub(const Matrix& A, size_t i1, size_t i2, size_t j1, size_t j2);
|
|||
void insertSub(Matrix& big, const Matrix& small, size_t i, size_t j);
|
||||
|
||||
/**
|
||||
* extracts a column from a matrix
|
||||
* NOTE: using this without the underscore is the ublas version!
|
||||
* Extracts a column view from a matrix that avoids a copy
|
||||
* @param matrix to extract column from
|
||||
* @param index of the column
|
||||
* @return the column in vector form
|
||||
* @return a const view of the matrix
|
||||
*/
|
||||
Vector column_(const Matrix& A, size_t j);
|
||||
template<class MATRIX>
|
||||
const typename MATRIX::ConstColXpr column(const MATRIX& A, size_t j) {
|
||||
return A.col(j);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a row view from a matrix that avoids a copy
|
||||
* @param matrix to extract row from
|
||||
* @param index of the row
|
||||
* @return a const view of the matrix
|
||||
*/
|
||||
template<class MATRIX>
|
||||
const typename MATRIX::ConstRowXpr row(const MATRIX& A, size_t j) {
|
||||
return A.row(j);
|
||||
}
|
||||
|
||||
/**
|
||||
* inserts a column into a matrix IN PLACE
|
||||
|
@ -210,15 +247,25 @@ Vector column_(const Matrix& A, size_t j);
|
|||
void insertColumn(Matrix& A, const Vector& col, size_t j);
|
||||
void insertColumn(Matrix& A, const Vector& col, size_t i, size_t j);
|
||||
|
||||
Vector columnNormSquare(const MatrixColMajor &A) ;
|
||||
Vector columnNormSquare(const MatrixColMajor &A);
|
||||
|
||||
/**
|
||||
* extracts a row from a matrix
|
||||
* @param matrix to extract row from
|
||||
* @param index of the row
|
||||
* @return the row in vector form
|
||||
* Zeros all of the elements below the diagonal of a matrix, in place
|
||||
* @param A is a matrix, to be modified in place
|
||||
* @param cols is the number of columns to zero, use zero for all columns
|
||||
*/
|
||||
Vector row_(const Matrix& A, size_t j);
|
||||
template<class MATRIX>
|
||||
void zeroBelowDiagonal(MATRIX& A, size_t cols=0) {
|
||||
const size_t m = A.rows(), n = A.cols();
|
||||
const size_t k = (cols) ? std::min(cols, std::min(m,n)) : std::min(m,n);
|
||||
for (size_t j=0; j<k; ++j)
|
||||
A.col(j).segment(j+1, m-(j+1)).setZero();
|
||||
}
|
||||
|
||||
/**
|
||||
* static transpose function, just calls Eigen transpose member function
|
||||
*/
|
||||
inline Matrix trans(const Matrix& A) { return A.transpose(); }
|
||||
|
||||
/**
|
||||
* solve AX=B via in-place Lu factorization and backsubstitution
|
||||
|
@ -239,10 +286,31 @@ Matrix inverse(const Matrix& A);
|
|||
*/
|
||||
std::pair<Matrix,Matrix> qr(const Matrix& A);
|
||||
|
||||
/**
|
||||
* QR factorization using Eigen's internal block QR algorithm
|
||||
* @param A is the input matrix, and is the output
|
||||
* @param clear_below_diagonal enables zeroing out below diagonal
|
||||
*/
|
||||
template <class MATRIX>
|
||||
void inplace_QR(MATRIX& A, bool clear_below_diagonal=true) {
|
||||
size_t rows = A.rows();
|
||||
size_t cols = A.cols();
|
||||
size_t size = std::min(rows,cols);
|
||||
|
||||
typedef Eigen::internal::plain_diag_type<MatrixColMajor>::type HCoeffsType;
|
||||
typedef Eigen::internal::plain_row_type<MatrixColMajor>::type RowVectorType;
|
||||
HCoeffsType hCoeffs(size);
|
||||
RowVectorType temp(cols);
|
||||
|
||||
Eigen::internal::householder_qr_inplace_blocked(A, hCoeffs, 48, temp.data());
|
||||
|
||||
zeroBelowDiagonal(A);
|
||||
}
|
||||
|
||||
/**
|
||||
* Imperative version of Householder rank 1 update
|
||||
*/
|
||||
void householder_update(Matrix &A, size_t j, double beta, const Vector& vjm);
|
||||
//void householder_update(Matrix &A, size_t j, double beta, const Vector& vjm);
|
||||
|
||||
/**
|
||||
* Imperative algorithm for in-place full elimination with
|
||||
|
@ -271,24 +339,43 @@ void householder_(Matrix& A, size_t k);
|
|||
*/
|
||||
void householder(Matrix& A, size_t k);
|
||||
|
||||
#ifdef GT_USE_LAPACK
|
||||
#ifdef USE_LAPACK_QR
|
||||
/**
|
||||
* Householder tranformation, zeros below diagonal
|
||||
* Householder tranformation, Householder vectors below diagonal
|
||||
* Column Major Version
|
||||
* @param k number of columns to zero out below diagonal
|
||||
* @param A matrix
|
||||
* @param copy_vectors - true to copy Householder vectors below diagonal
|
||||
* @return nothing: in place !!!
|
||||
*/
|
||||
void householder(Matrix& A);
|
||||
void householder_(MatrixColMajor& A, size_t k, bool copy_vectors=true);
|
||||
|
||||
/**
|
||||
* Householder tranformation directly on a column-major matrix. Does not zero
|
||||
* below the diagonal, so it will contain Householder vectors.
|
||||
* Householder tranformation, zeros below diagonal
|
||||
* Column Major version
|
||||
* @param k number of columns to zero out below diagonal
|
||||
* @param A matrix
|
||||
* @return nothing: in place !!!
|
||||
* FIXME: this uses the LAPACK QR function, so it cannot be used on Ubuntu (without
|
||||
* lots of hacks, at least)
|
||||
*/
|
||||
void householderColMajor(MatrixColMajor& A);
|
||||
#endif
|
||||
#endif
|
||||
void householder(MatrixColMajor& A, size_t k);
|
||||
|
||||
//#ifdef GT_USE_LAPACK
|
||||
//#ifdef USE_LAPACK_QR
|
||||
///**
|
||||
// * Householder tranformation, zeros below diagonal
|
||||
// * @return nothing: in place !!!
|
||||
// */
|
||||
//void householder(Matrix& A);
|
||||
//
|
||||
///**
|
||||
// * Householder tranformation directly on a column-major matrix. Does not zero
|
||||
// * below the diagonal, so it will contain Householder vectors.
|
||||
// * @return nothing: in place !!!
|
||||
// * FIXME: this uses the LAPACK QR function, so it cannot be used on Ubuntu (without
|
||||
// * lots of hacks, at least)
|
||||
// */
|
||||
//void householderColMajor(MatrixColMajor& A);
|
||||
//#endif
|
||||
//#endif
|
||||
|
||||
/**
|
||||
* backSubstitute U*x=b
|
||||
|
@ -296,11 +383,11 @@ void householderColMajor(MatrixColMajor& A);
|
|||
* @param b an RHS vector
|
||||
* @param unit, set true if unit triangular
|
||||
* @return the solution x of U*x=b
|
||||
* TODO: use boost
|
||||
*/
|
||||
template<class MATRIX, class VECTOR>
|
||||
Vector backSubstituteUpper(const boost::numeric::ublas::matrix_expression<MATRIX>& U,
|
||||
const boost::numeric::ublas::vector_expression<VECTOR>& b, bool unit=false);
|
||||
//FIXME: add back expression form
|
||||
//template<class MATRIX, class VECTOR>
|
||||
//Vector backSubstituteUpper(const MATRIX& U, const VECTOR& b, bool unit=false);
|
||||
Vector backSubstituteUpper(const Matrix& U, const Vector& b, bool unit=false);
|
||||
|
||||
/**
|
||||
* backSubstitute x'*U=b'
|
||||
|
@ -308,11 +395,11 @@ Vector backSubstituteUpper(const boost::numeric::ublas::matrix_expression<MATRIX
|
|||
* @param b an RHS vector
|
||||
* @param unit, set true if unit triangular
|
||||
* @return the solution x of x'*U=b'
|
||||
* TODO: use boost
|
||||
*/
|
||||
template<class VECTOR, class MATRIX>
|
||||
Vector backSubstituteUpper(const boost::numeric::ublas::vector_expression<VECTOR>& b,
|
||||
const boost::numeric::ublas::matrix_expression<MATRIX>& U, bool unit=false);
|
||||
//FIXME: add back expression form
|
||||
//template<class VECTOR, class MATRIX>
|
||||
//Vector backSubstituteUpper(const VECTOR& b, const MATRIX& U, bool unit=false);
|
||||
Vector backSubstituteUpper(const Vector& b, const Matrix& U, bool unit=false);
|
||||
|
||||
/**
|
||||
* backSubstitute L*x=b
|
||||
|
@ -320,7 +407,6 @@ Vector backSubstituteUpper(const boost::numeric::ublas::vector_expression<VECTOR
|
|||
* @param b an RHS vector
|
||||
* @param unit, set true if unit triangular
|
||||
* @return the solution x of L*x=b
|
||||
* TODO: use boost
|
||||
*/
|
||||
Vector backSubstituteLower(const Matrix& L, const Vector& d, bool unit=false);
|
||||
|
||||
|
@ -379,6 +465,40 @@ Matrix RtR(const Matrix& A);
|
|||
/** Return the inverse of a S.P.D. matrix. Inversion is done via Cholesky decomposition. */
|
||||
Matrix cholesky_inverse(const Matrix &A);
|
||||
|
||||
/**
|
||||
* SVD computes economy SVD A=U*S*V'
|
||||
* @param A an m*n matrix
|
||||
* @param U output argument: rotation matrix
|
||||
* @param S output argument: vector of singular values, sorted by default, pass false as last argument to avoid sorting!!!
|
||||
* @param V output argument: rotation matrix
|
||||
* if m > n then U*S*V' = (m*n)*(n*n)*(n*n) (the m-n columns of U are of no use)
|
||||
* if m < n then U*S*V' = (m*m)*(m*m)*(m*n) (the n-m columns of V are of no use)
|
||||
* Careful! The dimensions above reflect V', not V, which is n*m if m<n.
|
||||
* U is a basis in R^m, V is a basis in R^n
|
||||
* You can just pass empty matrices U,V, and vector S, they will be re-allocated.
|
||||
*/
|
||||
void svd(const Matrix& A, Matrix& U, Vector& S, Matrix& V);
|
||||
|
||||
/*
|
||||
* In place SVD, will throw an exception when m < n
|
||||
* @param A an m*n matrix is modified to contain U
|
||||
* @param S output argument: vector of singular values, sorted by default, pass false as last argument to avoid sorting!!!
|
||||
* @param V output argument: rotation matrix
|
||||
* if m > n then U*S*V' = (m*n)*(n*n)*(n*n) (the m-n columns of U are of no use)
|
||||
* You can just pass empty matrix V and vector S, they will be re-allocated.
|
||||
*/
|
||||
void svd(Matrix& A, Vector& S, Matrix& V);
|
||||
|
||||
/**
|
||||
* Direct linear transform algorithm that calls svd
|
||||
* to find a vector v that minimizes the algebraic error A*v
|
||||
* @param A of size m*n, where m>=n (pad with zero rows if not!)
|
||||
* Returns rank of A, minimum error (singular value),
|
||||
* and corresponding eigenvector (column of V, with A=U*S*V')
|
||||
*/
|
||||
boost::tuple<int, double, Vector>
|
||||
DLT(const Matrix& A, double rank_tol = 1e-9);
|
||||
|
||||
/**
|
||||
* Numerical exponential map, naive approach, not industrial strength !!!
|
||||
* @param A matrix to exponentiate
|
||||
|
@ -392,3 +512,38 @@ Matrix expm(const Matrix& A, size_t K=7);
|
|||
result_.addFailure(Failure(name_, __FILE__, __LINE__, #expected, #actual)); }
|
||||
|
||||
} // namespace gtsam
|
||||
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/split_free.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
// split version - sends sizes ahead
|
||||
template<class Archive>
|
||||
void save(Archive & ar, const Matrix & m, unsigned int version)
|
||||
{
|
||||
const int rows = m.rows(), cols = m.cols(), elements = rows*cols;
|
||||
std::vector<double> raw_data(elements);
|
||||
std::copy(m.data(), m.data()+elements, raw_data.begin());
|
||||
ar << make_nvp("rows", rows);
|
||||
ar << make_nvp("cols", cols);
|
||||
ar << make_nvp("data", raw_data);
|
||||
}
|
||||
template<class Archive>
|
||||
void load(Archive & ar, Matrix & m, unsigned int version)
|
||||
{
|
||||
size_t rows, cols;
|
||||
std::vector<double> raw_data;
|
||||
ar >> make_nvp("rows", rows);
|
||||
ar >> make_nvp("cols", cols);
|
||||
ar >> make_nvp("data", raw_data);
|
||||
m = Matrix(rows, cols);
|
||||
std::copy(raw_data.begin(), raw_data.end(), m.data());
|
||||
}
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_FREE(Matrix)
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
* -------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @file Vector.cpp
|
||||
* @brief typedef and functions to augment Boost's ublas::vector<double>
|
||||
* @author Kai Ni
|
||||
* @author Frank Dellaert
|
||||
*/
|
||||
* @file Vector.cpp
|
||||
* @brief typedef and functions to augment Boost's ublas::vector<double>
|
||||
* @author Kai Ni
|
||||
* @author Frank Dellaert
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <limits>
|
||||
|
@ -31,460 +31,456 @@
|
|||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include <boost/numeric/ublas/io.hpp>
|
||||
#include <boost/numeric/ublas/vector_proxy.hpp>
|
||||
#include <boost/random/normal_distribution.hpp>
|
||||
#include <boost/random/variate_generator.hpp>
|
||||
|
||||
#include <gtsam/base/Vector.h>
|
||||
|
||||
using namespace std;
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
/* ************************************************************************* */
|
||||
void odprintf_(const char *format, ostream& stream, ...) {
|
||||
char buf[4096], *p = buf;
|
||||
int n;
|
||||
|
||||
va_list args;
|
||||
va_start(args, stream);
|
||||
#ifdef WIN32
|
||||
n = _vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
|
||||
#else
|
||||
n = vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
|
||||
#endif
|
||||
va_end(args);
|
||||
|
||||
#ifdef WIN32
|
||||
OutputDebugString(buf);
|
||||
#else
|
||||
stream << buf;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
||||
void odprintf(const char *format, ...)
|
||||
{
|
||||
char buf[4096], *p = buf;
|
||||
int n;
|
||||
/* ************************************************************************* */
|
||||
void odprintf_(const char *format, ostream& stream, ...) {
|
||||
char buf[4096], *p = buf;
|
||||
int n;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
#ifdef WIN32
|
||||
n = _vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
|
||||
#else
|
||||
n = vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
|
||||
#endif
|
||||
va_end(args);
|
||||
va_list args;
|
||||
va_start(args, stream);
|
||||
#ifdef WIN32
|
||||
n = _vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
|
||||
#else
|
||||
n = vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
|
||||
#endif
|
||||
va_end(args);
|
||||
|
||||
#ifdef WIN32
|
||||
OutputDebugString(buf);
|
||||
#else
|
||||
cout << buf;
|
||||
#endif
|
||||
}
|
||||
#ifdef WIN32
|
||||
OutputDebugString(buf);
|
||||
#else
|
||||
stream << buf;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector Vector_( size_t m, const double* const data) {
|
||||
Vector v(m);
|
||||
copy(data, data+m, v.data().begin());
|
||||
return v;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector Vector_(size_t m, ...) {
|
||||
Vector v(m);
|
||||
va_list ap;
|
||||
va_start(ap, m);
|
||||
for( size_t i = 0 ; i < m ; i++) {
|
||||
double value = va_arg(ap, double);
|
||||
v(i) = value;
|
||||
}
|
||||
va_end(ap);
|
||||
return v;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool zero(const Vector& v) {
|
||||
bool result = true;
|
||||
size_t n = v.size();
|
||||
for( size_t j = 0 ; j < n ; j++)
|
||||
result = result && (v(j) == 0.0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector repeat(size_t n, double value) {
|
||||
Vector v(n, value);
|
||||
return v;
|
||||
}
|
||||
/* ************************************************************************* */
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector delta(size_t n, size_t i, double value) {
|
||||
Vector v = zero(n);
|
||||
v(i) = value;
|
||||
return v;
|
||||
}
|
||||
void odprintf(const char *format, ...)
|
||||
{
|
||||
char buf[4096], *p = buf;
|
||||
int n;
|
||||
|
||||
/* ************************************************************************* */
|
||||
void print(const Vector& v, const string& s, ostream& stream) {
|
||||
size_t n = v.size();
|
||||
odprintf_("%s [", stream, s.c_str());
|
||||
for(size_t i=0; i<n; i++)
|
||||
odprintf_("%g%s", stream, v[i], (i<n-1 ? "; " : ""));
|
||||
odprintf_("];\n", stream);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void save(const Vector& v, const string &s, const string& filename) {
|
||||
fstream stream(filename.c_str(), fstream::out | fstream::app);
|
||||
print(v, s + "=", stream);
|
||||
stream.close();
|
||||
}
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
#ifdef WIN32
|
||||
n = _vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
|
||||
#else
|
||||
n = vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
|
||||
#endif
|
||||
va_end(args);
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool operator==(const Vector& vec1,const Vector& vec2) {
|
||||
Vector::const_iterator it1 = vec1.begin();
|
||||
Vector::const_iterator it2 = vec2.begin();
|
||||
size_t m = vec1.size();
|
||||
for(size_t i=0; i<m; i++)
|
||||
if(it1[i] != it2[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool greaterThanOrEqual(const Vector& vec1, const Vector& vec2) {
|
||||
Vector::const_iterator it1 = vec1.begin();
|
||||
Vector::const_iterator it2 = vec2.begin();
|
||||
size_t m = vec1.size();
|
||||
for(size_t i=0; i<m; i++)
|
||||
if(!(it1[i] >= it2[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#ifdef WIN32
|
||||
OutputDebugString(buf);
|
||||
#else
|
||||
cout << buf;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool equal_with_abs_tol(const Vector& vec1, const Vector& vec2, double tol) {
|
||||
Vector::const_iterator it1 = vec1.begin();
|
||||
Vector::const_iterator it2 = vec2.begin();
|
||||
if (vec1.size()!=vec2.size()) return false;
|
||||
for(size_t i=0; i<vec1.size(); i++) {
|
||||
if(isnan(it1[i]) xor isnan(it2[i]))
|
||||
return false;
|
||||
if(fabs(it1[i] - it2[i]) > tol)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool assert_equal(const Vector& expected, const Vector& actual, double tol) {
|
||||
if (equal_with_abs_tol(expected,actual,tol)) return true;
|
||||
cout << "not equal:" << endl;
|
||||
print(expected, "expected");
|
||||
print(actual, "actual");
|
||||
return false;
|
||||
}
|
||||
/* ************************************************************************* */
|
||||
Vector Vector_( size_t m, const double* const data) {
|
||||
// Vector v(m);
|
||||
// for (size_t i=0; i<m; ++i)
|
||||
// v(i) = data[i];
|
||||
// return v;
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool assert_equal(SubVector expected, SubVector actual, double tol) {
|
||||
if (equal_with_abs_tol(expected,actual,tol)) return true;
|
||||
cout << "not equal:" << endl;
|
||||
print(expected, "expected");
|
||||
print(actual, "actual");
|
||||
return false;
|
||||
}
|
||||
Vector A(m);
|
||||
copy(data, data+m, A.data());
|
||||
return A;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool assert_equal(ConstSubVector expected, ConstSubVector actual, double tol) {
|
||||
if (equal_with_abs_tol(expected,actual,tol)) return true;
|
||||
cout << "not equal:" << endl;
|
||||
print(expected, "expected");
|
||||
print(actual, "actual");
|
||||
return false;
|
||||
}
|
||||
/* ************************************************************************* */
|
||||
Vector Vector_(size_t m, ...) {
|
||||
Vector v(m);
|
||||
va_list ap;
|
||||
va_start(ap, m);
|
||||
for( size_t i = 0 ; i < m ; i++) {
|
||||
double value = va_arg(ap, double);
|
||||
v(i) = value;
|
||||
}
|
||||
va_end(ap);
|
||||
return v;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool linear_dependent(const Vector& vec1, const Vector& vec2, double tol) {
|
||||
if (vec1.size()!=vec2.size()) return false;
|
||||
Vector::const_iterator it1 = vec1.begin();
|
||||
Vector::const_iterator it2 = vec2.begin();
|
||||
boost::optional<double> scale;
|
||||
for(size_t i=0; i<vec1.size(); i++) {
|
||||
if((fabs(it1[i])>tol&&fabs(it2[i])<tol) || (fabs(it1[i])<tol&&fabs(it2[i])>tol))
|
||||
return false;
|
||||
if(it1[i] == 0 && it2[i] == 0)
|
||||
continue;
|
||||
if (!scale)
|
||||
scale = it1[i] / it2[i];
|
||||
else if (fabs(it1[i] - it2[i] * (*scale)) > tol)
|
||||
return false;
|
||||
}
|
||||
return scale.is_initialized();
|
||||
}
|
||||
/* ************************************************************************* */
|
||||
Vector Vector_(const std::vector<double>& d) {
|
||||
Vector v(d.size());
|
||||
copy(d.begin(), d.end(), v.data());
|
||||
return v;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector sub(const Vector &v, size_t i1, size_t i2) {
|
||||
size_t n = i2-i1;
|
||||
Vector v_return(n);
|
||||
for( size_t i = 0; i < n; i++ )
|
||||
v_return(i) = v(i1 + i);
|
||||
return v_return;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void subInsert(Vector& big, const Vector& small, size_t i) {
|
||||
ublas::vector_range<Vector> colsubproxy(big, ublas::range (i, i+small.size()));
|
||||
colsubproxy = small;
|
||||
}
|
||||
/* ************************************************************************* */
|
||||
bool zero(const Vector& v) {
|
||||
bool result = true;
|
||||
size_t n = v.size();
|
||||
for( size_t j = 0 ; j < n ; j++)
|
||||
result = result && (v(j) == 0.0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector emul(const Vector &a, const Vector &b) {
|
||||
size_t n = a.size();
|
||||
assert (b.size()==n);
|
||||
Vector c(n);
|
||||
for( size_t i = 0; i < n; i++ )
|
||||
c(i) = a(i)*b(i);
|
||||
return c;
|
||||
/* ************************************************************************* */
|
||||
Vector repeat(size_t n, double value) {
|
||||
return Vector::Constant(n, value);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector delta(size_t n, size_t i, double value) {
|
||||
return Vector::Unit(n, i) * value;
|
||||
// Vector v = zero(n);
|
||||
// v(i) = value;
|
||||
// return v;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void print(const Vector& v, const string& s, ostream& stream) {
|
||||
size_t n = v.size();
|
||||
odprintf_("%s [", stream, s.c_str());
|
||||
for(size_t i=0; i<n; i++)
|
||||
odprintf_("%g%s", stream, v[i], (i<n-1 ? "; " : ""));
|
||||
odprintf_("];\n", stream);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void save(const Vector& v, const string &s, const string& filename) {
|
||||
fstream stream(filename.c_str(), fstream::out | fstream::app);
|
||||
print(v, s + "=", stream);
|
||||
stream.close();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool operator==(const Vector& vec1,const Vector& vec2) {
|
||||
if (vec1.size() != vec2.size()) return false;
|
||||
size_t m = vec1.size();
|
||||
for(size_t i=0; i<m; i++)
|
||||
if(vec1[i] != vec2[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool greaterThanOrEqual(const Vector& vec1, const Vector& vec2) {
|
||||
size_t m = vec1.size();
|
||||
for(size_t i=0; i<m; i++)
|
||||
if(!(vec1[i] >= vec2[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool equal_with_abs_tol(const Vector& vec1, const Vector& vec2, double tol) {
|
||||
if (vec1.size()!=vec2.size()) return false;
|
||||
size_t m = vec1.size();
|
||||
for(size_t i=0; i<m; ++i) {
|
||||
if(isnan(vec1[i]) xor isnan(vec2[i]))
|
||||
return false;
|
||||
if(fabs(vec1[i] - vec2[i]) > tol)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool equal_with_abs_tol(const SubVector& vec1, const SubVector& vec2, double tol) {
|
||||
if (vec1.size()!=vec2.size()) return false;
|
||||
size_t m = vec1.size();
|
||||
for(size_t i=0; i<m; ++i) {
|
||||
if(isnan(vec1[i]) xor isnan(vec2[i]))
|
||||
return false;
|
||||
if(fabs(vec1[i] - vec2[i]) > tol)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool assert_equal(const Vector& expected, const Vector& actual, double tol) {
|
||||
if (equal_with_abs_tol(expected,actual,tol)) return true;
|
||||
cout << "not equal:" << endl;
|
||||
print(expected, "expected");
|
||||
print(actual, "actual");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool assert_equal(SubVector expected, SubVector actual, double tol) {
|
||||
if (equal_with_abs_tol(expected,actual,tol)) return true;
|
||||
cout << "not equal:" << endl;
|
||||
print(expected, "expected");
|
||||
print(actual, "actual");
|
||||
return false;
|
||||
}
|
||||
|
||||
///* ************************************************************************* */
|
||||
//bool assert_equal(ConstSubVector expected, ConstSubVector actual, double tol) {
|
||||
// if (equal_with_abs_tol(Vector(expected),Vector(actual),tol)) return true;
|
||||
// cout << "not equal:" << endl;
|
||||
// print(Vector(expected), "expected");
|
||||
// print(Vector(actual), "actual");
|
||||
// return false;
|
||||
//}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool linear_dependent(const Vector& vec1, const Vector& vec2, double tol) {
|
||||
if (vec1.size()!=vec2.size()) return false;
|
||||
boost::optional<double> scale;
|
||||
size_t m = vec1.size();
|
||||
for(size_t i=0; i<m; i++) {
|
||||
if((fabs(vec1[i])>tol&&fabs(vec2[i])<tol) || (fabs(vec1[i])<tol&&fabs(vec2[i])>tol))
|
||||
return false;
|
||||
if(vec1[i] == 0 && vec2[i] == 0)
|
||||
continue;
|
||||
if (!scale)
|
||||
scale = vec1[i] / vec2[i];
|
||||
else if (fabs(vec1[i] - vec2[i] * (*scale)) > tol)
|
||||
return false;
|
||||
}
|
||||
return scale.is_initialized();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
ConstSubVector sub(const Vector &v, size_t i1, size_t i2) {
|
||||
return v.segment(i1,i2-i1);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void subInsert(Vector& big, const Vector& small, size_t i) {
|
||||
big.segment(i, small.size()) = small;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector emul(const Vector &a, const Vector &b) {
|
||||
assert (b.size()==a.size());
|
||||
return a.cwiseProduct(b);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector ediv(const Vector &a, const Vector &b) {
|
||||
assert (b.size()==a.size());
|
||||
return a.cwiseQuotient(b);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector ediv_(const Vector &a, const Vector &b) {
|
||||
size_t n = a.size();
|
||||
assert (b.size()==a.size());
|
||||
Vector c(n);
|
||||
for( size_t i = 0; i < n; i++ ) {
|
||||
double ai = a(i), bi = b(i);
|
||||
c(i) = (bi==0.0 && ai==0.0) ? 0.0 : a(i)/b(i);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double sum(const Vector &a) {
|
||||
return a.sum();
|
||||
// double result = 0.0;
|
||||
// size_t n = a.size();
|
||||
// for( size_t i = 0; i < n; i++ )
|
||||
// result += a(i);
|
||||
// return result;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double norm_2(const Vector& v) {
|
||||
return v.norm();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector reciprocal(const Vector &a) {
|
||||
size_t n = a.size();
|
||||
Vector b(n);
|
||||
for( size_t i = 0; i < n; i++ )
|
||||
b(i) = 1.0/a(i);
|
||||
return b;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector esqrt(const Vector& v) {
|
||||
return v.cwiseSqrt();
|
||||
// Vector s(v.size());
|
||||
// transform(v.begin(), v.end(), s.begin(), ::sqrt);
|
||||
// return s;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector abs(const Vector& v) {
|
||||
return v.cwiseAbs();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double max(const Vector &a) {
|
||||
return a.maxCoeff();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double dot(const Vector& a, const Vector& b) {
|
||||
assert (b.size()==a.size());
|
||||
return a.dot(b);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void scal(double alpha, Vector& x) {
|
||||
x *= alpha;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void axpy(double alpha, const Vector& x, Vector& y) {
|
||||
assert (y.size()==x.size());
|
||||
y += alpha * x;
|
||||
// size_t n = x.size();
|
||||
// for (size_t i = 0; i < n; i++)
|
||||
// y[i] += alpha * x[i];
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void axpy(double alpha, const Vector& x, SubVector y) {
|
||||
assert (y.size()==x.size());
|
||||
y += alpha * x;
|
||||
// size_t n = x.size();
|
||||
// for (size_t i = 0; i < n; i++)
|
||||
// y[i] += alpha * x[i];
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
// imperative version, pass in x
|
||||
double houseInPlace(Vector &v) {
|
||||
const double x0 = v(0);
|
||||
const double x02 = x0*x0;
|
||||
|
||||
// old code - GSL verison was actually a bit slower
|
||||
const double sigma = v.squaredNorm() - x02;
|
||||
|
||||
v(0) = 1.0;
|
||||
|
||||
if( sigma == 0.0 )
|
||||
return 0.0;
|
||||
else {
|
||||
double mu = sqrt(x02 + sigma);
|
||||
if( x0 <= 0.0 )
|
||||
v(0) = x0 - mu;
|
||||
else
|
||||
v(0) = -sigma / (x0 + mu);
|
||||
|
||||
const double v02 = v(0)*v(0);
|
||||
v = v / v(0);
|
||||
return 2.0 * v02 / (sigma + v02);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
pair<double, Vector > house(const Vector &x) {
|
||||
Vector v(x);
|
||||
double beta = houseInPlace(v);
|
||||
return make_pair(beta, v);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
// Fast version *no error checking* !
|
||||
// Pass in initialized vector of size m or will crash !
|
||||
double weightedPseudoinverse(const Vector& a, const Vector& weights,
|
||||
Vector& pseudo) {
|
||||
|
||||
size_t m = weights.size();
|
||||
static const double inf = std::numeric_limits<double>::infinity();
|
||||
|
||||
// Check once for zero entries of a. TODO: really needed ?
|
||||
vector<bool> isZero;
|
||||
for (size_t i = 0; i < m; ++i) isZero.push_back(fabs(a[i]) < 1e-9);
|
||||
|
||||
// If there is a valid (a!=0) constraint (sigma==0) return the first one
|
||||
for (size_t i = 0; i < m; ++i)
|
||||
if (weights[i] == inf && !isZero[i]) {
|
||||
pseudo = delta(m, i, 1 / a[i]);
|
||||
return inf;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector ediv(const Vector &a, const Vector &b) {
|
||||
size_t n = a.size();
|
||||
assert (b.size()==n);
|
||||
Vector c(n);
|
||||
for( size_t i = 0; i < n; i++ )
|
||||
c(i) = a(i)/b(i);
|
||||
return c;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector ediv_(const Vector &a, const Vector &b) {
|
||||
size_t n = a.size();
|
||||
assert (b.size()==n);
|
||||
Vector c(n);
|
||||
for( size_t i = 0; i < n; i++ ) {
|
||||
double ai = a(i), bi = b(i);
|
||||
c(i) = (bi==0.0 && ai==0.0) ? 0.0 : a(i)/b(i);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double sum(const Vector &a) {
|
||||
double result = 0.0;
|
||||
size_t n = a.size();
|
||||
for( size_t i = 0; i < n; i++ )
|
||||
result += a(i);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector reciprocal(const Vector &a) {
|
||||
size_t n = a.size();
|
||||
Vector b(n);
|
||||
for( size_t i = 0; i < n; i++ )
|
||||
b(i) = 1.0/a(i);
|
||||
return b;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector esqrt(const Vector& v) {
|
||||
Vector s(v.size());
|
||||
transform(v.begin(), v.end(), s.begin(), ::sqrt);
|
||||
return s;
|
||||
// Form psuedo-inverse inv(a'inv(Sigma)a)a'inv(Sigma)
|
||||
// For diagonal Sigma, inv(Sigma) = diag(precisions)
|
||||
double precision = 0;
|
||||
for (size_t i = 0; i < m; i++) {
|
||||
double ai = a[i];
|
||||
if (!isZero[i]) // also catches remaining sigma==0 rows
|
||||
precision += weights[i] * (ai * ai);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector abs(const Vector& v) {
|
||||
Vector s(v.size());
|
||||
transform(v.begin(), v.end(), s.begin(), ::fabs);
|
||||
return s;
|
||||
// precision = a'inv(Sigma)a
|
||||
if (precision < 1e-9)
|
||||
for (size_t i = 0; i < m; i++)
|
||||
pseudo[i] = 0;
|
||||
else {
|
||||
// emul(precisions,a)/precision
|
||||
double variance = 1.0 / precision;
|
||||
for (size_t i = 0; i < m; i++)
|
||||
pseudo[i] = isZero[i] ? 0 : variance * weights[i] * a[i];
|
||||
}
|
||||
return precision; // sum of weights
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
// Slow version with error checking
|
||||
pair<Vector, double>
|
||||
weightedPseudoinverse(const Vector& a, const Vector& weights) {
|
||||
int m = weights.size();
|
||||
if (a.size() != m)
|
||||
throw invalid_argument("a and weights have different sizes!");
|
||||
Vector pseudo(m);
|
||||
double precision = weightedPseudoinverse(a, weights, pseudo);
|
||||
return make_pair(pseudo, precision);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector concatVectors(const std::list<Vector>& vs)
|
||||
{
|
||||
size_t dim = 0;
|
||||
BOOST_FOREACH(Vector v, vs)
|
||||
dim += v.size();
|
||||
|
||||
Vector A(dim);
|
||||
size_t index = 0;
|
||||
BOOST_FOREACH(Vector v, vs) {
|
||||
for(int d = 0; d < v.size(); d++)
|
||||
A(d+index) = v(d);
|
||||
index += v.size();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double max(const Vector &a) {
|
||||
return *(std::max_element(a.begin(), a.end()));
|
||||
return A;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector concatVectors(size_t nrVectors, ...)
|
||||
{
|
||||
va_list ap;
|
||||
list<Vector> vs;
|
||||
va_start(ap, nrVectors);
|
||||
for( size_t i = 0 ; i < nrVectors ; i++) {
|
||||
Vector* V = va_arg(ap, Vector*);
|
||||
vs.push_back(*V);
|
||||
}
|
||||
va_end(ap);
|
||||
return concatVectors(vs);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double dot(const Vector& a, const Vector& b) {
|
||||
size_t n = a.size();
|
||||
assert (b.size()==n);
|
||||
double result = 0.0;
|
||||
for (size_t i = 0; i < n; i++)
|
||||
result += a[i] * b[i];
|
||||
return result;
|
||||
}
|
||||
/* ************************************************************************* */
|
||||
Vector rand_vector_norm(size_t dim, double mean, double sigma)
|
||||
{
|
||||
boost::normal_distribution<double> norm_dist(mean, sigma);
|
||||
boost::variate_generator<boost::minstd_rand&, boost::normal_distribution<double> > norm(generator, norm_dist);
|
||||
|
||||
/* ************************************************************************* */
|
||||
void scal(double alpha, Vector& x) {
|
||||
size_t n = x.size();
|
||||
for (size_t i = 0; i < n; i++)
|
||||
x[i] *= alpha;
|
||||
}
|
||||
Vector v(dim);
|
||||
for(int i = 0; i<v.size(); ++i)
|
||||
v(i) = norm();
|
||||
|
||||
/* ************************************************************************* */
|
||||
void axpy(double alpha, const Vector& x, Vector& y) {
|
||||
size_t n = x.size();
|
||||
assert (y.size()==n);
|
||||
for (size_t i = 0; i < n; i++)
|
||||
y[i] += alpha * x[i];
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void axpy(double alpha, const Vector& x, SubVector y) {
|
||||
size_t n = x.size();
|
||||
assert (y.size()==n);
|
||||
for (size_t i = 0; i < n; i++)
|
||||
y[i] += alpha * x[i];
|
||||
}
|
||||
/* ************************************************************************* */
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector operator/(double s, const Vector& v) {
|
||||
Vector result(v.size());
|
||||
for(size_t i = 0; i < v.size(); i++)
|
||||
result[i] = s / v[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
// imperative version, pass in x
|
||||
double houseInPlace(Vector &v) {
|
||||
const double x0 = v(0);
|
||||
const double x02 = x0*x0;
|
||||
|
||||
// old code - GSL verison was actually a bit slower
|
||||
const double sigma = inner_prod(v,v) - x02;
|
||||
|
||||
v(0) = 1.0;
|
||||
|
||||
if( sigma == 0.0 )
|
||||
return 0.0;
|
||||
else {
|
||||
double mu = sqrt(x02 + sigma);
|
||||
if( x0 <= 0.0 )
|
||||
v(0) = x0 - mu;
|
||||
else
|
||||
v(0) = -sigma / (x0 + mu);
|
||||
|
||||
const double v02 = v(0)*v(0);
|
||||
v = v / v(0);
|
||||
return 2.0 * v02 / (sigma + v02);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
pair<double, Vector > house(const Vector &x) {
|
||||
Vector v(x);
|
||||
double beta = houseInPlace(v);
|
||||
return make_pair(beta, v);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
// Fast version *no error checking* !
|
||||
// Pass in initialized vector of size m or will crash !
|
||||
double weightedPseudoinverse(const Vector& a, const Vector& weights,
|
||||
Vector& pseudo) {
|
||||
|
||||
size_t m = weights.size();
|
||||
static const double inf = std::numeric_limits<double>::infinity();
|
||||
|
||||
// Check once for zero entries of a. TODO: really needed ?
|
||||
vector<bool> isZero;
|
||||
for (size_t i = 0; i < m; ++i) isZero.push_back(fabs(a[i]) < 1e-9);
|
||||
|
||||
// If there is a valid (a!=0) constraint (sigma==0) return the first one
|
||||
for (size_t i = 0; i < m; ++i)
|
||||
if (weights[i] == inf && !isZero[i]) {
|
||||
pseudo = delta(m, i, 1 / a[i]);
|
||||
return inf;
|
||||
}
|
||||
|
||||
// Form psuedo-inverse inv(a'inv(Sigma)a)a'inv(Sigma)
|
||||
// For diagonal Sigma, inv(Sigma) = diag(precisions)
|
||||
double precision = 0;
|
||||
for (size_t i = 0; i < m; i++) {
|
||||
double ai = a[i];
|
||||
if (!isZero[i]) // also catches remaining sigma==0 rows
|
||||
precision += weights[i] * (ai * ai);
|
||||
}
|
||||
|
||||
// precision = a'inv(Sigma)a
|
||||
if (precision < 1e-9)
|
||||
for (size_t i = 0; i < m; i++)
|
||||
pseudo[i] = 0;
|
||||
else {
|
||||
// emul(precisions,a)/precision
|
||||
double variance = 1.0 / precision;
|
||||
for (size_t i = 0; i < m; i++)
|
||||
pseudo[i] = isZero[i] ? 0 : variance * weights[i] * a[i];
|
||||
}
|
||||
return precision; // sum of weights
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
// Slow version with error checking
|
||||
pair<Vector, double>
|
||||
weightedPseudoinverse(const Vector& a, const Vector& weights) {
|
||||
size_t m = weights.size();
|
||||
if (a.size() != m)
|
||||
throw invalid_argument("a and weights have different sizes!");
|
||||
Vector pseudo(m);
|
||||
double precision = weightedPseudoinverse(a, weights, pseudo);
|
||||
return make_pair(pseudo, precision);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector concatVectors(const std::list<Vector>& vs)
|
||||
{
|
||||
size_t dim = 0;
|
||||
BOOST_FOREACH(Vector v, vs)
|
||||
dim += v.size();
|
||||
|
||||
Vector A(dim);
|
||||
size_t index = 0;
|
||||
BOOST_FOREACH(Vector v, vs) {
|
||||
for(size_t d = 0; d < v.size(); d++)
|
||||
A(d+index) = v(d);
|
||||
index += v.size();
|
||||
}
|
||||
|
||||
return A;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector concatVectors(size_t nrVectors, ...)
|
||||
{
|
||||
va_list ap;
|
||||
list<Vector> vs;
|
||||
va_start(ap, nrVectors);
|
||||
for( size_t i = 0 ; i < nrVectors ; i++) {
|
||||
Vector* V = va_arg(ap, Vector*);
|
||||
vs.push_back(*V);
|
||||
}
|
||||
va_end(ap);
|
||||
return concatVectors(vs);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector rand_vector_norm(size_t dim, double mean, double sigma)
|
||||
{
|
||||
boost::normal_distribution<double> norm_dist(mean, sigma);
|
||||
boost::variate_generator<boost::minstd_rand&, boost::normal_distribution<double> > norm(generator, norm_dist);
|
||||
|
||||
Vector v(dim);
|
||||
Vector::iterator it_v;
|
||||
for(it_v=v.begin(); it_v!=v.end(); it_v++)
|
||||
*it_v = norm();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
||||
} // namespace gtsam
|
||||
|
|
|
@ -21,17 +21,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <boost/numeric/ublas/vector.hpp>
|
||||
#include <boost/numeric/ublas/vector_proxy.hpp>
|
||||
#include <vector>
|
||||
#include <gtsam/3rdparty/Eigen/Core>
|
||||
#include <boost/random/linear_congruential.hpp>
|
||||
|
||||
// Vector is a *global* typedef
|
||||
// wrap-matlab does this typedef as well
|
||||
#if ! defined (MEX_H)
|
||||
typedef boost::numeric::ublas::vector<double> Vector;
|
||||
#endif
|
||||
typedef boost::numeric::ublas::vector_range<Vector> SubVector;
|
||||
typedef boost::numeric::ublas::vector_range<const Vector> ConstSubVector;
|
||||
// TODO: fix matlab wrapper
|
||||
//#if ! defined (MEX_H)
|
||||
//typedef boost::numeric::ublas::vector<double> Vector;
|
||||
//#endif
|
||||
|
||||
// Typedef arbitary length vector
|
||||
typedef Eigen::VectorXd Vector;
|
||||
|
||||
typedef Eigen::VectorBlock<Vector> SubVector;
|
||||
typedef Eigen::VectorBlock<const Vector> ConstSubVector;
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
|
@ -51,6 +56,11 @@ Vector Vector_( size_t m, const double* const data);
|
|||
*/
|
||||
Vector Vector_(size_t m, ...);
|
||||
|
||||
/**
|
||||
* Create a numeric vector from an STL vector of doubles
|
||||
*/
|
||||
Vector Vector_(const std::vector<double>& data);
|
||||
|
||||
/**
|
||||
* Create vector initialized to a constant value
|
||||
* @param size
|
||||
|
@ -81,13 +91,13 @@ inline Vector basis(size_t n, size_t i) { return delta(n, i, 1.0); }
|
|||
* Create zero vector
|
||||
* @param size
|
||||
*/
|
||||
inline Vector zero(size_t n) { return repeat(n,0.0);}
|
||||
inline Vector zero(size_t n) { return Vector::Zero(n);}
|
||||
|
||||
/**
|
||||
* Create vector initialized to ones
|
||||
* @param size
|
||||
*/
|
||||
inline Vector ones(size_t n) { return repeat(n,1.0);}
|
||||
inline Vector ones(size_t n) { return Vector::Ones(n); }
|
||||
|
||||
/**
|
||||
* check if all zero
|
||||
|
@ -125,6 +135,7 @@ bool greaterThanOrEqual(const Vector& v1, const Vector& v2);
|
|||
* VecA == VecB up to tolerance
|
||||
*/
|
||||
bool equal_with_abs_tol(const Vector& vec1, const Vector& vec2, double tol=1e-9);
|
||||
bool equal_with_abs_tol(const SubVector& vec1, const SubVector& vec2, double tol=1e-9);
|
||||
|
||||
/**
|
||||
* Override of equal in Lie.h
|
||||
|
@ -157,7 +168,7 @@ bool assert_equal(const Vector& vec1, const Vector& vec2, double tol=1e-9);
|
|||
* @return bool
|
||||
*/
|
||||
bool assert_equal(SubVector vec1, SubVector vec2, double tol=1e-9);
|
||||
bool assert_equal(ConstSubVector vec1, ConstSubVector vec2, double tol=1e-9);
|
||||
//bool assert_equal(ConstSubVector vec1, ConstSubVector vec2, double tol=1e-9);
|
||||
|
||||
/**
|
||||
* check whether two vectors are linearly dependent
|
||||
|
@ -175,7 +186,7 @@ bool linear_dependent(const Vector& vec1, const Vector& vec2, double tol=1e-9);
|
|||
* @param i2 last row index + 1
|
||||
* @return subvector v(i1:i2)
|
||||
*/
|
||||
Vector sub(const Vector &v, size_t i1, size_t i2);
|
||||
ConstSubVector sub(const Vector &v, size_t i1, size_t i2);
|
||||
|
||||
/**
|
||||
* Inserts a subvector into a vector IN PLACE
|
||||
|
@ -216,6 +227,14 @@ Vector ediv_(const Vector &a, const Vector &b);
|
|||
*/
|
||||
double sum(const Vector &a);
|
||||
|
||||
/**
|
||||
* Calculates L2 norm for a vector
|
||||
* modeled after boost.ublas for compatibility
|
||||
* @param vector
|
||||
* @return the L2 norm
|
||||
*/
|
||||
double norm_2(const Vector& v);
|
||||
|
||||
/**
|
||||
* elementwise reciprocal of vector elements
|
||||
* @param a vector
|
||||
|
@ -247,6 +266,7 @@ double max(const Vector &a);
|
|||
/** Dot product */
|
||||
double dot(const Vector &a, const Vector& b);
|
||||
|
||||
// TODO: remove simple blas functions - these are one-liners with Eigen
|
||||
/**
|
||||
* BLAS Level 1 scal: x <- alpha*x
|
||||
*/
|
||||
|
@ -258,11 +278,6 @@ void scal(double alpha, Vector& x);
|
|||
void axpy(double alpha, const Vector& x, Vector& y);
|
||||
void axpy(double alpha, const Vector& x, SubVector y);
|
||||
|
||||
/**
|
||||
* Divide every element of a Vector into a scalar
|
||||
*/
|
||||
Vector operator/(double s, const Vector& v);
|
||||
|
||||
/**
|
||||
* house(x,j) computes HouseHolder vector v and scaling factor beta
|
||||
* from x, such that the corresponding Householder reflection zeroes out
|
||||
|
@ -310,5 +325,34 @@ Vector rand_vector_norm(size_t dim, double mean = 0, double sigma = 1);
|
|||
|
||||
} // namespace gtsam
|
||||
|
||||
// FIXME: make this go away - use the Sampler class instead
|
||||
static boost::minstd_rand generator(42u);
|
||||
|
||||
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/split_free.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
|
||||
// split version - copies into an STL vector for serialization
|
||||
template<class Archive>
|
||||
void save(Archive & ar, const Vector & v, unsigned int version)
|
||||
{
|
||||
const size_t n = v.size();
|
||||
std::vector<double> raw_data(n);
|
||||
copy(v.data(), v.data()+n, raw_data.begin());
|
||||
ar << make_nvp("data", raw_data);
|
||||
}
|
||||
template<class Archive>
|
||||
void load(Archive & ar, Vector & v, unsigned int version)
|
||||
{
|
||||
std::vector<double> raw_data;
|
||||
ar >> make_nvp("data", raw_data);
|
||||
v = gtsam::Vector_(raw_data);
|
||||
}
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_FREE(Vector)
|
||||
|
|
|
@ -18,60 +18,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <boost/numeric/ublas/matrix_proxy.hpp>
|
||||
#include <gtsam/3rdparty/Eigen/Dense>
|
||||
#include <gtsam/3rdparty/Eigen/Core>
|
||||
#include <gtsam/base/Matrix.h>
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
/** This is a wrapper around ublas::matrix_column that stores a copy of a
|
||||
* ublas::matrix_range. This does not copy the matrix data itself. The
|
||||
* purpose of this class is to be allow a column-of-a-range to be returned
|
||||
* from a function, given that a standard column-of-a-range just stores a
|
||||
* reference to the range. The stored range stores a reference to the original
|
||||
* matrix.
|
||||
*/
|
||||
template<class MATRIX>
|
||||
class BlockColumn : public boost::numeric::ublas::vector_expression<BlockColumn<MATRIX> > {
|
||||
protected:
|
||||
typedef boost::numeric::ublas::matrix_range<MATRIX> Range;
|
||||
typedef boost::numeric::ublas::matrix_column<Range> Base;
|
||||
Range range_;
|
||||
Base base_;
|
||||
public:
|
||||
typedef BlockColumn<MATRIX> Self;
|
||||
typedef typename Base::matrix_type matrix_type;
|
||||
typedef typename Base::size_type size_type;
|
||||
typedef typename Base::difference_type difference_type;
|
||||
typedef typename Base::value_type value_type;
|
||||
typedef typename Base::const_reference const_reference;
|
||||
typedef typename Base::reference reference;
|
||||
typedef typename Base::storage_category storage_category;
|
||||
typedef Self closure_type;
|
||||
typedef const Self const_closure_type;
|
||||
typedef typename Base::iterator iterator;
|
||||
typedef typename Base::const_iterator const_iterator;
|
||||
|
||||
BlockColumn(const boost::numeric::ublas::matrix_range<MATRIX>& block, size_t column) :
|
||||
range_(block), base_(range_, column) {}
|
||||
BlockColumn(const BlockColumn& rhs) :
|
||||
range_(rhs.range_), base_(rhs.base_) {}
|
||||
BlockColumn& operator=(const BlockColumn& rhs) { base_.operator=(rhs.base_); return *this; }
|
||||
template<class AE> BlockColumn& operator=(const boost::numeric::ublas::vector_expression<AE>& rhs) { base_.operator=(rhs); return *this; }
|
||||
typename Base::size_type size() const { return base_.size(); }
|
||||
const typename Base::matrix_closure_type& data() const { return base_.data(); }
|
||||
typename Base::matrix_closure_type& data() { return base_.data(); }
|
||||
typename Base::const_reference operator()(typename Base::size_type i) const { return base_(i); }
|
||||
typename Base::reference operator()(typename Base::size_type i) { return base_(i); }
|
||||
BlockColumn& assign_temporary(BlockColumn& rhs) { base_.assign_temporary(rhs.base_); return *this; }
|
||||
BlockColumn& assign_temporary(Base& rhs) { base_.assign_temporary(rhs); return *this; }
|
||||
bool same_closure(const BlockColumn& rhs) { return base_.same_closure(rhs.base_); }
|
||||
bool same_closure(const Base& rhs) { return base_.same_closure(rhs); }
|
||||
template<class AE> BlockColumn& assign(const boost::numeric::ublas::vector_expression<AE>& rhs) { base_.assign(rhs); return *this; }
|
||||
iterator begin() { return base_.begin(); }
|
||||
const_iterator begin() const { return base_.begin(); }
|
||||
iterator end() { return base_.end(); }
|
||||
const_iterator end() const { return base_.end(); }
|
||||
};
|
||||
|
||||
template<class MATRIX> class SymmetricBlockView;
|
||||
|
||||
/**
|
||||
|
@ -95,10 +47,12 @@ template<class MATRIX>
|
|||
class VerticalBlockView {
|
||||
public:
|
||||
typedef MATRIX FullMatrix;
|
||||
typedef typename boost::numeric::ublas::matrix_range<MATRIX> Block;
|
||||
typedef typename boost::numeric::ublas::matrix_range<const MATRIX> constBlock;
|
||||
typedef BlockColumn<MATRIX> Column;
|
||||
typedef BlockColumn<const MATRIX> constColumn;
|
||||
typedef Eigen::Block<MATRIX> Block;
|
||||
typedef Eigen::Block<const MATRIX> constBlock;
|
||||
|
||||
// columns of blocks
|
||||
typedef Eigen::VectorBlock<typename MATRIX::ColXpr> Column;
|
||||
typedef Eigen::VectorBlock<const typename MATRIX::ConstColXpr> constColumn;
|
||||
|
||||
protected:
|
||||
FullMatrix& matrix_; // the reference to the full matrix
|
||||
|
@ -112,18 +66,19 @@ protected:
|
|||
public:
|
||||
/** Construct from an empty matrix (asserts that the matrix is empty) */
|
||||
VerticalBlockView(FullMatrix& matrix) :
|
||||
matrix_(matrix), rowStart_(0), rowEnd_(matrix_.size1()), blockStart_(0) {
|
||||
matrix_(matrix), rowStart_(0), rowEnd_(matrix_.rows()), blockStart_(0) {
|
||||
fillOffsets((size_t*)0, (size_t*)0);
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct from a non-empty matrix and copy the block structure from
|
||||
* another block view. */
|
||||
* another block view.
|
||||
*/
|
||||
template<class RHS>
|
||||
VerticalBlockView(FullMatrix& matrix, const RHS& rhs) :
|
||||
matrix_(matrix) {
|
||||
if(matrix_.size1() != rhs.size1() || matrix_.size2() != rhs.size2())
|
||||
if((size_t) matrix_.rows() != rhs.rows() || (size_t) matrix_.cols() != rhs.cols())
|
||||
throw std::invalid_argument(
|
||||
"In VerticalBlockView<>(FullMatrix& matrix, const RHS& rhs), matrix and rhs must\n"
|
||||
"already be of the same size. If not, construct the VerticalBlockView from an\n"
|
||||
|
@ -136,12 +91,13 @@ public:
|
|||
/** Construct from iterators over the sizes of each vertical block */
|
||||
template<typename ITERATOR>
|
||||
VerticalBlockView(FullMatrix& matrix, ITERATOR firstBlockDim, ITERATOR lastBlockDim) :
|
||||
matrix_(matrix), rowStart_(0), rowEnd_(matrix_.size1()), blockStart_(0) {
|
||||
matrix_(matrix), rowStart_(0), rowEnd_(matrix_.rows()), blockStart_(0) {
|
||||
fillOffsets(firstBlockDim, lastBlockDim);
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/** Construct from a vector of the sizes of each vertical block, resize the
|
||||
/**
|
||||
* Construct from a vector of the sizes of each vertical block, resize the
|
||||
* matrix so that its height is matrixNewHeight and its width fits the given
|
||||
* block dimensions.
|
||||
*/
|
||||
|
@ -149,17 +105,17 @@ public:
|
|||
VerticalBlockView(FullMatrix& matrix, ITERATOR firstBlockDim, ITERATOR lastBlockDim, size_t matrixNewHeight) :
|
||||
matrix_(matrix), rowStart_(0), rowEnd_(matrixNewHeight), blockStart_(0) {
|
||||
fillOffsets(firstBlockDim, lastBlockDim);
|
||||
matrix_.resize(matrixNewHeight, variableColOffsets_.back(), false);
|
||||
matrix_.resize(matrixNewHeight, variableColOffsets_.back());
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/** Row size
|
||||
*/
|
||||
size_t size1() const { assertInvariants(); return rowEnd_ - rowStart_; }
|
||||
size_t rows() const { assertInvariants(); return rowEnd_ - rowStart_; }
|
||||
|
||||
/** Column size
|
||||
*/
|
||||
size_t size2() const { assertInvariants(); return variableColOffsets_.back() - variableColOffsets_[blockStart_]; }
|
||||
size_t cols() const { assertInvariants(); return variableColOffsets_.back() - variableColOffsets_[blockStart_]; }
|
||||
|
||||
|
||||
/** Block count
|
||||
|
@ -167,60 +123,62 @@ public:
|
|||
size_t nBlocks() const { assertInvariants(); return variableColOffsets_.size() - 1 - blockStart_; }
|
||||
|
||||
|
||||
Block operator()(size_t block) {
|
||||
/** Access a single block in the underlying matrix with read/write access */
|
||||
inline Block operator()(size_t block) {
|
||||
return range(block, block+1);
|
||||
}
|
||||
|
||||
constBlock operator()(size_t block) const {
|
||||
/** Access a const block view */
|
||||
inline const constBlock operator()(size_t block) const {
|
||||
return range(block, block+1);
|
||||
}
|
||||
|
||||
Block range(size_t startBlock, size_t endBlock) {
|
||||
/** access ranges of blocks at a time */
|
||||
inline Block range(size_t startBlock, size_t endBlock) {
|
||||
assertInvariants();
|
||||
size_t actualStartBlock = startBlock + blockStart_;
|
||||
size_t actualEndBlock = endBlock + blockStart_;
|
||||
checkBlock(actualStartBlock);
|
||||
assert(actualEndBlock < variableColOffsets_.size());
|
||||
return Block(matrix_,
|
||||
boost::numeric::ublas::range(rowStart_, rowEnd_),
|
||||
boost::numeric::ublas::range(variableColOffsets_[actualStartBlock], variableColOffsets_[actualEndBlock]));
|
||||
const size_t& startCol = variableColOffsets_[actualStartBlock];
|
||||
const size_t& endCol = variableColOffsets_[actualEndBlock];
|
||||
return matrix_.block(rowStart_, startCol, rowEnd_-rowStart_, endCol-startCol);
|
||||
}
|
||||
|
||||
constBlock range(size_t startBlock, size_t endBlock) const {
|
||||
inline const constBlock range(size_t startBlock, size_t endBlock) const {
|
||||
assertInvariants();
|
||||
size_t actualStartBlock = startBlock + blockStart_;
|
||||
size_t actualEndBlock = endBlock + blockStart_;
|
||||
checkBlock(actualStartBlock);
|
||||
assert(actualEndBlock < variableColOffsets_.size());
|
||||
return constBlock(matrix_,
|
||||
boost::numeric::ublas::range(rowStart_, rowEnd_),
|
||||
boost::numeric::ublas::range(variableColOffsets_[actualStartBlock], variableColOffsets_[actualEndBlock]));
|
||||
const size_t& startCol = variableColOffsets_[actualStartBlock];
|
||||
const size_t& endCol = variableColOffsets_[actualEndBlock];
|
||||
return ((const FullMatrix&)matrix_).block(rowStart_, startCol, rowEnd_-rowStart_, endCol-startCol);
|
||||
}
|
||||
|
||||
Block full() {
|
||||
inline Block full() {
|
||||
return range(0,nBlocks());
|
||||
}
|
||||
|
||||
constBlock full() const {
|
||||
inline const constBlock full() const {
|
||||
return range(0,nBlocks());
|
||||
}
|
||||
|
||||
/** get a single column out of a block */
|
||||
Column column(size_t block, size_t columnOffset) {
|
||||
assertInvariants();
|
||||
size_t actualBlock = block + blockStart_;
|
||||
checkBlock(actualBlock);
|
||||
assert(variableColOffsets_[actualBlock] + columnOffset < variableColOffsets_[actualBlock+1]);
|
||||
Block blockMat(operator()(block));
|
||||
return Column(blockMat, columnOffset);
|
||||
return matrix_.col(variableColOffsets_[actualBlock] + columnOffset).segment(rowStart_, rowEnd_-rowStart_);
|
||||
}
|
||||
|
||||
constColumn column(size_t block, size_t columnOffset) const {
|
||||
const constColumn column(size_t block, size_t columnOffset) const {
|
||||
assertInvariants();
|
||||
size_t actualBlock = block + blockStart_;
|
||||
checkBlock(actualBlock);
|
||||
assert(variableColOffsets_[actualBlock] + columnOffset < matrix_.size2());
|
||||
constBlock blockMat(operator()(block));
|
||||
return constColumn(blockMat, columnOffset);
|
||||
assert(variableColOffsets_[actualBlock] + columnOffset < (size_t) matrix_.cols());
|
||||
return ((const FullMatrix&)matrix_).col(variableColOffsets_[actualBlock] + columnOffset).segment(rowStart_, rowEnd_-rowStart_);
|
||||
}
|
||||
|
||||
size_t offset(size_t block) const {
|
||||
|
@ -237,17 +195,21 @@ public:
|
|||
size_t rowEnd() const { return rowEnd_; }
|
||||
size_t firstBlock() const { return blockStart_; }
|
||||
|
||||
/** Copy the block structure and resize the underlying matrix, but do not
|
||||
/** access to full matrix */
|
||||
const FullMatrix& fullMatrix() const { return matrix_; }
|
||||
|
||||
/**
|
||||
* Copy the block structure and resize the underlying matrix, but do not
|
||||
* copy the matrix data. If blockStart(), rowStart(), and/or rowEnd() have
|
||||
* been modified, this copies the structure of the corresponding matrix view.
|
||||
* In the destination VerticalBlockView, blockStart() and rowStart() will
|
||||
* thus be 0, rowEnd() will be size2() of the source VerticalBlockView, and
|
||||
* thus be 0, rowEnd() will be cols() of the source VerticalBlockView, and
|
||||
* the underlying matrix will be the size of the view of the source matrix.
|
||||
*/
|
||||
template<class RHS>
|
||||
void copyStructureFrom(const RHS& rhs) {
|
||||
if(matrix_.size1() != rhs.size1() || matrix_.size2() != rhs.size2())
|
||||
matrix_.resize(rhs.size1(), rhs.size2(), false);
|
||||
if((size_t) matrix_.rows() != (size_t) rhs.rows() || (size_t) matrix_.cols() != (size_t) rhs.cols())
|
||||
matrix_.resize(rhs.rows(), rhs.cols());
|
||||
if(rhs.blockStart_ == 0)
|
||||
variableColOffsets_ = rhs.variableColOffsets_;
|
||||
else {
|
||||
|
@ -261,7 +223,7 @@ public:
|
|||
}
|
||||
}
|
||||
rowStart_ = 0;
|
||||
rowEnd_ = matrix_.size1();
|
||||
rowEnd_ = matrix_.rows();
|
||||
blockStart_ = 0;
|
||||
assertInvariants();
|
||||
}
|
||||
|
@ -275,13 +237,14 @@ public:
|
|||
* If blockStart(), rowStart(), and/or rowEnd() have been modified, this
|
||||
* copies the structure of the corresponding matrix view. In the destination
|
||||
* VerticalBlockView, blockStart() and rowStart() will thus be 0, rowEnd()
|
||||
* will be size2() of the source VerticalBlockView, and the underlying matrix
|
||||
* will be cols() of the source VerticalBlockView, and the underlying matrix
|
||||
* will be the size of the view of the source matrix.
|
||||
*/
|
||||
template<class RHS>
|
||||
VerticalBlockView<MATRIX>& assignNoalias(const RHS& rhs) {
|
||||
copyStructureFrom(rhs);
|
||||
boost::numeric::ublas::noalias(matrix_) = rhs.full();
|
||||
// boost::numeric::ublas::noalias(matrix_) = rhs.full();
|
||||
matrix_ = rhs.full(); // FIXME: check if noalias is necessary here
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -300,17 +263,17 @@ public:
|
|||
|
||||
protected:
|
||||
void assertInvariants() const {
|
||||
assert(matrix_.size2() == variableColOffsets_.back());
|
||||
assert((size_t) matrix_.cols() == variableColOffsets_.back());
|
||||
assert(blockStart_ < variableColOffsets_.size());
|
||||
assert(rowStart_ <= matrix_.size1());
|
||||
assert(rowEnd_ <= matrix_.size1());
|
||||
assert(rowStart_ <= (size_t) matrix_.rows());
|
||||
assert(rowEnd_ <= (size_t) matrix_.rows());
|
||||
assert(rowStart_ <= rowEnd_);
|
||||
}
|
||||
|
||||
void checkBlock(size_t block) const {
|
||||
assert(matrix_.size2() == variableColOffsets_.back());
|
||||
assert((size_t) matrix_.cols() == variableColOffsets_.back());
|
||||
assert(block < variableColOffsets_.size()-1);
|
||||
assert(variableColOffsets_[block] < matrix_.size2() && variableColOffsets_[block+1] <= matrix_.size2());
|
||||
assert(variableColOffsets_[block] < (size_t) matrix_.cols() && variableColOffsets_[block+1] <= (size_t) matrix_.cols());
|
||||
}
|
||||
|
||||
template<typename ITERATOR>
|
||||
|
@ -328,7 +291,6 @@ protected:
|
|||
template<class RELATED> friend class VerticalBlockView;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This class stores a *reference* to a matrix and allows it to be accessed as
|
||||
* a collection of blocks. It also provides for accessing individual
|
||||
|
@ -348,12 +310,14 @@ template<class MATRIX>
|
|||
class SymmetricBlockView {
|
||||
public:
|
||||
typedef MATRIX FullMatrix;
|
||||
typedef typename boost::numeric::ublas::matrix_range<MATRIX> Block;
|
||||
typedef typename boost::numeric::ublas::matrix_range<const MATRIX> constBlock;
|
||||
typedef BlockColumn<MATRIX> Column;
|
||||
typedef BlockColumn<const MATRIX> constColumn;
|
||||
typedef Eigen::Block<MATRIX> Block;
|
||||
typedef Eigen::Block<const MATRIX> constBlock;
|
||||
|
||||
// typedef typename MATRIX::ColXpr Column;
|
||||
// typedef typename MATRIX::ConstColXpr constColumn;
|
||||
|
||||
protected:
|
||||
static FullMatrix matrixTemp_; // the reference to the full matrix
|
||||
FullMatrix& matrix_; // the reference to the full matrix
|
||||
std::vector<size_t> variableColOffsets_; // the starting columns of each block (0-based)
|
||||
|
||||
|
@ -385,16 +349,19 @@ public:
|
|||
void resize(ITERATOR firstBlockDim, ITERATOR lastBlockDim, bool preserve) {
|
||||
blockStart_ = 0;
|
||||
fillOffsets(firstBlockDim, lastBlockDim);
|
||||
matrix_.resize(variableColOffsets_.back(), variableColOffsets_.back(), preserve);
|
||||
if (preserve)
|
||||
matrix_.conservativeResize(variableColOffsets_.back(), variableColOffsets_.back());
|
||||
else
|
||||
matrix_.resize(variableColOffsets_.back(), variableColOffsets_.back());
|
||||
}
|
||||
|
||||
/** Row size
|
||||
*/
|
||||
size_t size1() const { assertInvariants(); return variableColOffsets_.back() - variableColOffsets_[blockStart_]; }
|
||||
size_t rows() const { assertInvariants(); return variableColOffsets_.back() - variableColOffsets_[blockStart_]; }
|
||||
|
||||
/** Column size
|
||||
*/
|
||||
size_t size2() const { return size1(); }
|
||||
size_t cols() const { return rows(); }
|
||||
|
||||
|
||||
/** Block count
|
||||
|
@ -420,9 +387,10 @@ public:
|
|||
checkBlock(j_actualStartBlock);
|
||||
assert(i_actualEndBlock < variableColOffsets_.size());
|
||||
assert(j_actualEndBlock < variableColOffsets_.size());
|
||||
return Block(matrix_,
|
||||
boost::numeric::ublas::range(variableColOffsets_[i_actualStartBlock], variableColOffsets_[i_actualEndBlock]),
|
||||
boost::numeric::ublas::range(variableColOffsets_[j_actualStartBlock], variableColOffsets_[j_actualEndBlock]));
|
||||
return matrix_.block(
|
||||
variableColOffsets_[i_actualStartBlock], variableColOffsets_[j_actualStartBlock],
|
||||
variableColOffsets_[i_actualEndBlock]-variableColOffsets_[i_actualStartBlock],
|
||||
variableColOffsets_[j_actualEndBlock]-variableColOffsets_[j_actualStartBlock]);
|
||||
}
|
||||
|
||||
constBlock range(size_t i_startBlock, size_t i_endBlock, size_t j_startBlock, size_t j_endBlock) const {
|
||||
|
@ -435,9 +403,10 @@ public:
|
|||
checkBlock(j_actualStartBlock);
|
||||
assert(i_actualEndBlock < variableColOffsets_.size());
|
||||
assert(j_actualEndBlock < variableColOffsets_.size());
|
||||
return constBlock(matrix_,
|
||||
boost::numeric::ublas::range(variableColOffsets_[i_actualStartBlock], variableColOffsets_[i_actualEndBlock]),
|
||||
boost::numeric::ublas::range(variableColOffsets_[j_actualStartBlock], variableColOffsets_[j_actualEndBlock]));
|
||||
return ((const FullMatrix&)matrix_).block(
|
||||
variableColOffsets_[i_actualStartBlock], variableColOffsets_[j_actualStartBlock],
|
||||
variableColOffsets_[i_actualEndBlock]-variableColOffsets_[i_actualStartBlock],
|
||||
variableColOffsets_[j_actualEndBlock]-variableColOffsets_[j_actualStartBlock]);
|
||||
}
|
||||
|
||||
Block full() {
|
||||
|
@ -448,12 +417,32 @@ public:
|
|||
return range(0,nBlocks(), 0,nBlocks());
|
||||
}
|
||||
|
||||
/** access to full matrix */
|
||||
const FullMatrix& fullMatrix() const { return matrix_; }
|
||||
|
||||
// typedef typename MATRIX::ColXpr Column;
|
||||
typedef typeof(matrixTemp_.col(0).segment(0, 1)) Column;
|
||||
typedef typeof(((const FullMatrix&)matrixTemp_).col(0).segment(0, 1)) constColumn;
|
||||
|
||||
Column column(size_t i_block, size_t j_block, size_t columnOffset) {
|
||||
assertInvariants();
|
||||
size_t j_actualBlock = j_block + blockStart_;
|
||||
assert(variableColOffsets_[j_actualBlock] + columnOffset < variableColOffsets_[j_actualBlock+1]);
|
||||
Block blockMat(operator()(i_block, j_block));
|
||||
return Column(blockMat, columnOffset);
|
||||
assertInvariants();
|
||||
// size_t j_actualBlock = j_block + blockStart_;
|
||||
// assert(variableColOffsets_[j_actualBlock] + columnOffset < variableColOffsets_[j_actualBlock+1]);
|
||||
// Block blockMat(operator()(i_block, j_block));
|
||||
// return blockMat.col(columnOffset);
|
||||
|
||||
size_t i_actualBlock = i_block + blockStart_;
|
||||
size_t j_actualBlock = j_block + blockStart_;
|
||||
checkBlock(i_actualBlock);
|
||||
checkBlock(j_actualBlock);
|
||||
assert(i_actualBlock < variableColOffsets_.size());
|
||||
assert(j_actualBlock < variableColOffsets_.size());
|
||||
assert(variableColOffsets_[j_actualBlock] + columnOffset < variableColOffsets_[j_actualBlock+1]);
|
||||
|
||||
return matrix_.col(
|
||||
variableColOffsets_[j_actualBlock] + columnOffset).segment(
|
||||
variableColOffsets_[i_actualBlock],
|
||||
variableColOffsets_[i_actualBlock+1]-variableColOffsets_[i_actualBlock]);
|
||||
}
|
||||
|
||||
constColumn column(size_t i_block, size_t j_block, size_t columnOffset) const {
|
||||
|
@ -466,18 +455,48 @@ public:
|
|||
|
||||
Column rangeColumn(size_t i_startBlock, size_t i_endBlock, size_t j_block, size_t columnOffset) {
|
||||
assertInvariants();
|
||||
size_t j_actualBlock = j_block + blockStart_;
|
||||
assert(variableColOffsets_[j_actualBlock] + columnOffset < variableColOffsets_[j_actualBlock+1]);
|
||||
Block blockMat(this->range(i_startBlock, i_endBlock, j_block));
|
||||
return Column(blockMat, columnOffset);
|
||||
|
||||
size_t i_actualStartBlock = i_startBlock + blockStart_;
|
||||
size_t i_actualEndBlock = i_endBlock + blockStart_;
|
||||
size_t j_actualStartBlock = j_block + blockStart_;
|
||||
checkBlock(i_actualStartBlock);
|
||||
checkBlock(j_actualStartBlock);
|
||||
assert(i_actualEndBlock < variableColOffsets_.size());
|
||||
assert(variableColOffsets_[j_actualStartBlock] + columnOffset < variableColOffsets_[j_actualStartBlock+1]);
|
||||
|
||||
return matrix_.col(
|
||||
variableColOffsets_[j_actualStartBlock] + columnOffset).segment(
|
||||
variableColOffsets_[i_actualStartBlock],
|
||||
variableColOffsets_[i_actualEndBlock]-variableColOffsets_[i_actualStartBlock]);
|
||||
|
||||
// column of a block approach
|
||||
// size_t j_actualBlock = j_block + blockStart_;
|
||||
// assert(variableColOffsets_[j_actualBlock] + columnOffset < variableColOffsets_[j_actualBlock+1]);
|
||||
// Block blockMat = this->range(i_startBlock, i_endBlock, j_block, j_block+1);
|
||||
// return Column(blockMat, columnOffset);
|
||||
}
|
||||
|
||||
constColumn rangeColumn(size_t i_startBlock, size_t i_endBlock, size_t j_block, size_t columnOffset) const {
|
||||
assertInvariants();
|
||||
size_t j_actualBlock = j_block + blockStart_;
|
||||
assert(variableColOffsets_[j_actualBlock] + columnOffset < variableColOffsets_[j_actualBlock+1]);
|
||||
constBlock blockMat(this->range(i_startBlock, i_endBlock, j_block, j_block+1));
|
||||
return constColumn(blockMat, columnOffset);
|
||||
|
||||
size_t i_actualStartBlock = i_startBlock + blockStart_;
|
||||
size_t i_actualEndBlock = i_endBlock + blockStart_;
|
||||
size_t j_actualStartBlock = j_block + blockStart_;
|
||||
checkBlock(i_actualStartBlock);
|
||||
checkBlock(j_actualStartBlock);
|
||||
assert(i_actualEndBlock < variableColOffsets_.size());
|
||||
assert(variableColOffsets_[j_actualStartBlock] + columnOffset < variableColOffsets_[j_actualStartBlock+1]);
|
||||
|
||||
return ((const FullMatrix&)matrix_).col(
|
||||
variableColOffsets_[j_actualStartBlock] + columnOffset).segment(
|
||||
variableColOffsets_[i_actualStartBlock],
|
||||
variableColOffsets_[i_actualEndBlock]-variableColOffsets_[i_actualStartBlock]);
|
||||
|
||||
// column of a block approach
|
||||
// size_t j_actualBlock = j_block + blockStart_;
|
||||
// assert(variableColOffsets_[j_actualBlock] + columnOffset < variableColOffsets_[j_actualBlock+1]);
|
||||
// constBlock blockMat = this->range(i_startBlock, i_endBlock, j_block, j_block+1);
|
||||
// return constColumn(blockMat, columnOffset);
|
||||
}
|
||||
|
||||
size_t offset(size_t block) const {
|
||||
|
@ -498,7 +517,7 @@ public:
|
|||
*/
|
||||
template<class RHS>
|
||||
void copyStructureFrom(const RHS& rhs) {
|
||||
matrix_.resize(rhs.size2(), rhs.size2(), false);
|
||||
matrix_.resize(rhs.cols(), rhs.cols());
|
||||
if(rhs.blockStart_ == 0)
|
||||
variableColOffsets_ = rhs.variableColOffsets_;
|
||||
else {
|
||||
|
@ -529,7 +548,8 @@ public:
|
|||
template<class RHSMATRIX>
|
||||
SymmetricBlockView<MATRIX>& assignNoalias(const SymmetricBlockView<RHSMATRIX>& rhs) {
|
||||
copyStructureFrom(rhs);
|
||||
boost::numeric::ublas::noalias(matrix_) = rhs.range(0, rhs.nBlocks(), 0, rhs.nBlocks());
|
||||
// boost::numeric::ublas::noalias(matrix_) = rhs.range(0, rhs.nBlocks(), 0, rhs.nBlocks());
|
||||
matrix_ = rhs.matrix_.block(0, 0, rhs.nBlocks(), rhs.nBlocks());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -546,16 +566,16 @@ public:
|
|||
|
||||
protected:
|
||||
void assertInvariants() const {
|
||||
assert(matrix_.size1() == matrix_.size2());
|
||||
assert(matrix_.size2() == variableColOffsets_.back());
|
||||
assert(matrix_.rows() == matrix_.cols());
|
||||
assert((size_t) matrix_.cols() == variableColOffsets_.back());
|
||||
assert(blockStart_ < variableColOffsets_.size());
|
||||
}
|
||||
|
||||
void checkBlock(size_t block) const {
|
||||
assert(matrix_.size1() == matrix_.size2());
|
||||
assert(matrix_.size2() == variableColOffsets_.back());
|
||||
assert(matrix_.rows() == matrix_.cols());
|
||||
assert((size_t) matrix_.cols() == variableColOffsets_.back());
|
||||
assert(block < variableColOffsets_.size()-1);
|
||||
assert(variableColOffsets_[block] < matrix_.size2() && variableColOffsets_[block+1] <= matrix_.size2());
|
||||
assert(variableColOffsets_[block] < (size_t) matrix_.cols() && variableColOffsets_[block+1] <= (size_t) matrix_.cols());
|
||||
}
|
||||
|
||||
template<typename ITERATOR>
|
||||
|
|
|
@ -18,18 +18,14 @@
|
|||
|
||||
#include <gtsam/base/debug.h>
|
||||
#include <gtsam/base/cholesky.h>
|
||||
#include <gtsam/base/lapack.h>
|
||||
#include <gtsam/base/timing.h>
|
||||
|
||||
#include <gtsam/3rdparty/Eigen/Core>
|
||||
#include <gtsam/3rdparty/Eigen/Dense>
|
||||
|
||||
#include <boost/numeric/ublas/matrix_proxy.hpp>
|
||||
#include <boost/numeric/ublas/symmetric.hpp>
|
||||
#include <boost/numeric/ublas/blas.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
//namespace ublas = boost::numeric::ublas;
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -39,90 +35,6 @@ namespace gtsam {
|
|||
static const double zeroPivotThreshold = 1e-6;
|
||||
static const double underconstrainedPrior = 1e-5;
|
||||
|
||||
/* ************************************************************************* */
|
||||
void cholesky_inplace(MatrixColMajor& I) {
|
||||
|
||||
// We do not check for symmetry but we do check for squareness
|
||||
assert(I.size1() == I.size2());
|
||||
|
||||
// Do Cholesky, return value info as follows (from dpotrf.f):
|
||||
// 00054 * INFO (output) INTEGER
|
||||
// 00055 * = 0: successful exit
|
||||
// 00056 * < 0: if INFO = -i, the i-th argument had an illegal value
|
||||
// 00057 * > 0: if INFO = i, the leading minor of order i is not
|
||||
// 00058 * positive definite, and the factorization could not be
|
||||
// 00059 * completed.
|
||||
int info = lapack_dpotrf('U', I.size1(), &I(0,0), I.size1());
|
||||
if(info != 0) {
|
||||
if(info < 0)
|
||||
throw std::domain_error(boost::str(boost::format(
|
||||
"Bad input to cholesky_inplace, dpotrf returned %d.\n")%info));
|
||||
else
|
||||
throw std::domain_error("The matrix passed into cholesky_inplace is rank-deficient");
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
size_t choleskyFactorUnderdetermined(MatrixColMajor& Ab, size_t nFrontal) {
|
||||
|
||||
static const bool debug = false;
|
||||
|
||||
size_t m = Ab.size1();
|
||||
size_t n = Ab.size2();
|
||||
|
||||
// If m >= n, this function will just compute the plain Cholesky
|
||||
// factorization of A'A. If m < n, A'A is rank-deficient this function
|
||||
// instead computes the upper-trapazoidal factor [ R S ], as described in the
|
||||
// header file comment.
|
||||
// size_t rank = std::min(m,n-1);
|
||||
size_t rank = nFrontal;
|
||||
|
||||
if(rank > 0) {
|
||||
|
||||
// F is the first 'rank' columns of Ab, G is the remaining columns
|
||||
ublas::matrix_range<MatrixColMajor> F(ublas::project(Ab, ublas::range(0,m), ublas::range(0,rank)));
|
||||
ublas::matrix_range<MatrixColMajor> G(ublas::project(Ab, ublas::range(0,m), ublas::range(rank,n)));
|
||||
|
||||
if(debug) {
|
||||
print(F, "F: ");
|
||||
print(G, "G: ");
|
||||
}
|
||||
|
||||
ublas::matrix_range<MatrixColMajor> R(ublas::project(Ab, ublas::range(0,rank), ublas::range(0,rank)));
|
||||
ublas::matrix_range<MatrixColMajor> S(ublas::project(Ab, ublas::range(0,rank), ublas::range(rank,n)));
|
||||
|
||||
// First compute F' * G (ublas makes a copy here to avoid aliasing)
|
||||
if(S.size2() > 0)
|
||||
S = ublas::prod(ublas::trans(F), G);
|
||||
|
||||
// ublas makes a copy to avoid aliasing on this assignment
|
||||
R = ublas::prod(ublas::trans(F), F);
|
||||
|
||||
// Compute the values of R from F'F
|
||||
int info = lapack_dpotrf('U', rank, &R(0,0), Ab.size1());
|
||||
if(info != 0) {
|
||||
if(info < 0)
|
||||
throw std::domain_error(boost::str(boost::format(
|
||||
"Bad input to choleskyFactorUnderdetermined, dpotrf returned %d.\n")%info));
|
||||
else
|
||||
throw std::domain_error(boost::str(boost::format(
|
||||
"The matrix passed into choleskyFactorUnderdetermined is numerically rank-deficient, dpotrf returned rank=%d, expected rank was %d.\n")%(info-1)%rank));
|
||||
}
|
||||
|
||||
// Compute S = inv(R') * F' * G, i.e. solve S when R'S = F'G
|
||||
if(S.size2() > 0)
|
||||
cblas_dtrsm(CblasColMajor, CblasLeft, CblasUpper, CblasTrans, CblasNonUnit, S.size1(), S.size2(), 1.0, &R(0,0), m, &S(0,0), m);
|
||||
|
||||
if(debug) {
|
||||
print(R, "R: ");
|
||||
print(S, "S: ");
|
||||
}
|
||||
|
||||
return m;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
static inline bool choleskyStep(MatrixColMajor& ATA, size_t k, size_t order) {
|
||||
|
||||
|
@ -146,15 +58,18 @@ static inline bool choleskyStep(MatrixColMajor& ATA, size_t k, size_t order) {
|
|||
ATA(k,k) = beta;
|
||||
|
||||
if(k < (order-1)) {
|
||||
ublas::matrix_row<MatrixColMajor> Vf(ublas::row(ATA, k));
|
||||
ublas::vector_range<typeof(Vf)> V(ublas::subrange(Vf, k+1,order));
|
||||
// ublas::matrix_row<MatrixColMajor> Vf(ublas::row(ATA, k));
|
||||
// ublas::vector_range<typeof(Vf)> V(ublas::subrange(Vf, k+1,order));
|
||||
|
||||
// Update A(k,k+1:end) <- A(k,k+1:end) / beta
|
||||
V *= betainv;
|
||||
typedef typeof(ATA.row(k).segment(k+1, order-(k+1))) BlockRow;
|
||||
BlockRow V = ATA.row(k).segment(k+1, order-(k+1));
|
||||
V *= betainv;
|
||||
|
||||
// Update A(k+1:end, k+1:end) <- A(k+1:end, k+1:end) - v*v' / alpha
|
||||
ublas::matrix_range<MatrixColMajor> L(ublas::subrange(ATA, k+1,order, k+1,order));
|
||||
L -= ublas::outer_prod(V, V);
|
||||
// ublas::matrix_range<MatrixColMajor> L(ublas::subrange(ATA, k+1,order, k+1,order));
|
||||
// L -= ublas::outer_prod(V, V);
|
||||
ATA.block(k+1, k+1, order-(k+1), order-(k+1)) -= V.transpose() * V;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -173,10 +88,10 @@ pair<size_t,bool> choleskyCareful(MatrixColMajor& ATA, int order) {
|
|||
const bool debug = ISDEBUG("choleskyCareful");
|
||||
|
||||
// Check that the matrix is square (we do not check for symmetry)
|
||||
assert(ATA.size1() == ATA.size2());
|
||||
assert(ATA.rows() == ATA.cols());
|
||||
|
||||
// Number of rows/columns
|
||||
const size_t n = ATA.size1();
|
||||
const size_t n = ATA.rows();
|
||||
|
||||
// Negative order means factor the entire matrix
|
||||
if(order < 0)
|
||||
|
@ -204,11 +119,11 @@ pair<size_t,bool> choleskyCareful(MatrixColMajor& ATA, int order) {
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void choleskyPartial(MatrixColMajor& ABCublas, size_t nFrontal) {
|
||||
void choleskyPartial(MatrixColMajor& ABC, size_t nFrontal) {
|
||||
|
||||
const bool debug = ISDEBUG("choleskyPartial");
|
||||
|
||||
Eigen::Map<Eigen::MatrixXd> ABC(&ABCublas(0,0), ABCublas.size1(), ABCublas.size2());
|
||||
// Eigen::Map<Eigen::MatrixXd> ABC(&ABCublas(0,0), ABCublas.rows(), ABCublas.cols());
|
||||
|
||||
assert(ABC.rows() == ABC.cols());
|
||||
assert(ABC.rows() >= 0 && nFrontal <= size_t(ABC.rows()));
|
||||
|
|
|
@ -21,29 +21,6 @@
|
|||
|
||||
namespace gtsam {
|
||||
|
||||
/** Plain Cholesky on a symmetric positive semi-definite matrix, in place. */
|
||||
void cholesky_inplace(MatrixColMajor& I);
|
||||
|
||||
/**
|
||||
* Factor an underdetermined Gaussian into a Gaussian conditional. This means
|
||||
* for a Gaussian exp(-1/2 * ||Ax - b||^2), with a "wide" A, i.e. m < n, to
|
||||
* find an upper-triangular m x m R, rectangular m x (n-m) S, and m-vector d,
|
||||
* such that ||Ax - b||^2 == || [R S]x - d ||^2.
|
||||
*
|
||||
* The matrices [ R S ] and [ R S d ] are each upper-trapazoidal.
|
||||
*
|
||||
* This returns the same upper-trapazoidal factor as QR, but uses Cholesky for
|
||||
* efficiency. Given a matrix [ F G b ], with F square, this first computes
|
||||
* the upper-triangular R = chol(F), i.e. R'R == F'F. It then computes the
|
||||
* upper-trapazoidal factor [ R S d ], with [ S d ] = inv(R') * F' * [ G b ].
|
||||
*
|
||||
* Note that this operates on the Jacobian A matrix, not the symmetric
|
||||
* information matrix like plain Cholesky.
|
||||
*
|
||||
* This function returns the rank of the factor.
|
||||
*/
|
||||
size_t choleskyFactorUnderdetermined(MatrixColMajor& Ab, size_t nFrontal);
|
||||
|
||||
/**
|
||||
* "Careful" Cholesky computes the positive square-root of a positive symmetric
|
||||
* semi-definite matrix (i.e. that may be rank-deficient). Unlike standard
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
|
||||
* 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 lapack.h
|
||||
* @brief Handles wrapping of LAPACK functions that we use
|
||||
* @author Richard Roberts
|
||||
* @created Nov 6, 2010
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Prototypes of LAPACK functions that we use
|
||||
extern "C" {
|
||||
|
||||
#include <cblas.h>
|
||||
|
||||
/* FORTRAN subroutine */
|
||||
int dpotrf_(char *uplo, int *n, double *a, int *lda, int *info);
|
||||
|
||||
/* C wrapper */
|
||||
inline int lapack_dpotrf(char uplo, int n, double* a, int lda) {
|
||||
int info;
|
||||
dpotrf_(&uplo, &n, a, &lda, &info);
|
||||
return info;
|
||||
}
|
||||
|
||||
int dpotf2_(char *uplo, int *n, double *a, int *lda, int *info);
|
||||
|
||||
inline int lapack_dpotf2(char uplo, int n, double* a, int lda) {
|
||||
int info;
|
||||
dpotf2_(&uplo, &n, a, &lda, &info);
|
||||
return info;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -66,7 +66,7 @@ namespace gtsam {
|
|||
Vector numericalGradient(boost::function<double(const X&)> h, const X& x, double delta=1e-5) {
|
||||
double factor = 1.0/(2.0*delta);
|
||||
const size_t n = x.dim();
|
||||
Vector d(n,0.0), g(n,0.0);
|
||||
Vector d = zero(n), g = zero(n);
|
||||
for (size_t j=0;j<n;j++) {
|
||||
d(j) += delta; double hxplus = h(x.expmap(d));
|
||||
d(j) -= 2*delta; double hxmin = h(x.expmap(d));
|
||||
|
@ -95,7 +95,7 @@ namespace gtsam {
|
|||
Y hx = h(x);
|
||||
double factor = 1.0/(2.0*delta);
|
||||
const size_t m = hx.dim(), n = x.dim();
|
||||
Vector d(n,0.0);
|
||||
Vector d = zero(n);
|
||||
Matrix H = zeros(m,n);
|
||||
for (size_t j=0;j<n;j++) {
|
||||
d(j) += delta; Vector hxplus = hx.logmap(h(x.expmap(d)));
|
||||
|
@ -149,7 +149,7 @@ namespace gtsam {
|
|||
Y hx = h(x1,x2);
|
||||
double factor = 1.0/(2.0*delta);
|
||||
const size_t m = hx.dim(), n = x1.dim();
|
||||
Vector d(n,0.0);
|
||||
Vector d = zero(n);
|
||||
Matrix H = zeros(m,n);
|
||||
for (size_t j=0;j<n;j++) {
|
||||
d(j) += delta; Vector hxplus = hx.logmap(h(x1.expmap(d),x2));
|
||||
|
@ -213,7 +213,7 @@ namespace gtsam {
|
|||
Y hx = h(x1,x2);
|
||||
double factor = 1.0/(2.0*delta);
|
||||
const size_t m = hx.dim(), n = x2.dim();
|
||||
Vector d(n,0.0);
|
||||
Vector d = zero(n);
|
||||
Matrix H = zeros(m,n);
|
||||
for (size_t j=0;j<n;j++) {
|
||||
d(j) += delta; Vector hxplus = hx.logmap(h(x1,x2.expmap(d)));
|
||||
|
@ -279,7 +279,7 @@ namespace gtsam {
|
|||
Y hx = h(x1,x2,x3);
|
||||
double factor = 1.0/(2.0*delta);
|
||||
const size_t m = hx.dim(), n = x1.dim();
|
||||
Vector d(n,0.0);
|
||||
Vector d = zero(n);
|
||||
Matrix H = zeros(m,n);
|
||||
for (size_t j=0;j<n;j++) {
|
||||
d(j) += delta; Vector hxplus = hx.logmap(h(x1.expmap(d),x2,x3));
|
||||
|
@ -344,7 +344,7 @@ namespace gtsam {
|
|||
Y hx = h(x1,x2,x3);
|
||||
double factor = 1.0/(2.0*delta);
|
||||
const size_t m = hx.dim(), n = x2.dim();
|
||||
Vector d(n,0.0);
|
||||
Vector d = zero(n);
|
||||
Matrix H = zeros(m,n);
|
||||
for (size_t j=0;j<n;j++) {
|
||||
d(j) += delta; Vector hxplus = hx.logmap(h(x1, x2.expmap(d),x3));
|
||||
|
@ -409,7 +409,7 @@ namespace gtsam {
|
|||
Y hx = h(x1,x2,x3);
|
||||
double factor = 1.0/(2.0*delta);
|
||||
const size_t m = hx.dim(), n = x3.dim();
|
||||
Vector d(n,0.0);
|
||||
Vector d = zero(n);
|
||||
Matrix H = zeros(m,n);
|
||||
for (size_t j=0;j<n;j++) {
|
||||
d(j) += delta; Vector hxplus = hx.logmap(h(x1, x2, x3.expmap(d)));
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/**
|
||||
* @file testBlockMatrices
|
||||
* @author Alex Cunningham
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <CppUnitLite/TestHarness.h>
|
||||
#include <gtsam/base/blockMatrices.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace gtsam;
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST(testBlockMatrices, jacobian_factor1) {
|
||||
typedef MatrixColMajor AbMatrix;
|
||||
typedef VerticalBlockView<AbMatrix> BlockAb;
|
||||
|
||||
AbMatrix matrix; // actual matrix - empty to start with
|
||||
|
||||
// from JacobianFactor::Constructor - one variable
|
||||
Matrix A1 = Matrix_(2,3,
|
||||
1., 2., 3.,
|
||||
4., 5., 6.);
|
||||
Vector b = Vector_(2, 7., 8.);
|
||||
size_t dims[] = { A1.cols(), 1};
|
||||
|
||||
// build the structure
|
||||
BlockAb Ab(matrix, dims, dims+2, b.size());
|
||||
|
||||
// add a matrix and get back out
|
||||
Ab(0) = A1;
|
||||
EXPECT(assert_equal(A1, Ab(0)));
|
||||
|
||||
// add vector to the system
|
||||
Ab.column(1, 0) = b;
|
||||
EXPECT(assert_equal(A1, Ab(0)));
|
||||
EXPECT(assert_equal(b, Ab.column(1,0)));
|
||||
|
||||
// examine matrix contents
|
||||
EXPECT_LONGS_EQUAL(2, Ab.nBlocks());
|
||||
Matrix expFull = Matrix_(2, 4,
|
||||
1., 2., 3., 7.,
|
||||
4., 5., 6., 8.);
|
||||
Matrix actFull = Ab.full();
|
||||
EXPECT(assert_equal(expFull, actFull));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST(testBlockMatrices, jacobian_factor2) {
|
||||
typedef MatrixColMajor AbMatrix;
|
||||
typedef VerticalBlockView<AbMatrix> BlockAb;
|
||||
|
||||
AbMatrix matrix; // actual matrix - empty to start with
|
||||
|
||||
// from JacobianFactor::Constructor - two variables
|
||||
Matrix A1 = Matrix_(2,3,
|
||||
1., 2., 3.,
|
||||
4., 5., 6.);
|
||||
Matrix A2 = Matrix_(2,1,
|
||||
10.,
|
||||
11.);
|
||||
Vector b = Vector_(2, 7., 8.);
|
||||
size_t dims[] = { A1.cols(), A2.cols(), 1};
|
||||
|
||||
// build the structure
|
||||
BlockAb Ab(matrix, dims, dims+3, b.size());
|
||||
|
||||
// add blocks
|
||||
Ab(0) = A1;
|
||||
Ab(1) = A2;
|
||||
EXPECT(assert_equal(A1, Ab(0)));
|
||||
EXPECT(assert_equal(A2, Ab(1)));
|
||||
|
||||
// add vector to the system
|
||||
Ab.column(2, 0) = b;
|
||||
EXPECT(assert_equal(A1, Ab(0)));
|
||||
EXPECT(assert_equal(A2, Ab(1)));
|
||||
EXPECT(assert_equal(b, Ab.column(2,0)));
|
||||
|
||||
// examine matrix contents
|
||||
EXPECT_LONGS_EQUAL(3, Ab.nBlocks());
|
||||
Matrix expFull = Matrix_(2, 5,
|
||||
1., 2., 3., 10., 7.,
|
||||
4., 5., 6., 11., 8.);
|
||||
Matrix actFull = Ab.full();
|
||||
EXPECT(assert_equal(expFull, actFull));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST(testBlockMatrices, hessian_factor1) {
|
||||
typedef MatrixColMajor InfoMatrix;
|
||||
typedef SymmetricBlockView<InfoMatrix> BlockInfo;
|
||||
|
||||
Matrix expected_full = Matrix_(3, 3,
|
||||
3.0, 5.0, -8.0,
|
||||
0.0, 6.0, -9.0,
|
||||
0.0, 0.0, 10.0);
|
||||
|
||||
Matrix G = Matrix_(2,2, 3.0, 5.0, 0.0, 6.0);
|
||||
Vector g = Vector_(2, -8.0, -9.0);
|
||||
double f = 10.0;
|
||||
|
||||
size_t dims[] = { G.rows(), 1 };
|
||||
InfoMatrix fullMatrix = zeros(G.rows() + 1, G.rows() + 1);
|
||||
BlockInfo infoView(fullMatrix, dims, dims+2);
|
||||
infoView(0,0) = G;
|
||||
infoView.column(0,1,0) = g;
|
||||
infoView(1,1)(0,0) = f;
|
||||
|
||||
EXPECT_LONGS_EQUAL(0, infoView.blockStart());
|
||||
EXPECT_LONGS_EQUAL(2, infoView.nBlocks());
|
||||
EXPECT(assert_equal(InfoMatrix(expected_full), fullMatrix));
|
||||
EXPECT(assert_equal(InfoMatrix(G), infoView.range(0, 1, 0, 1)))
|
||||
EXPECT_DOUBLES_EQUAL(f, infoView(1, 1)(0,0), 1e-10);
|
||||
|
||||
EXPECT(assert_equal(g, Vector(infoView.rangeColumn(0, 1, 1, 0))));
|
||||
EXPECT(assert_equal(g, Vector(((const BlockInfo)infoView).rangeColumn(0, 1, 1, 0))));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
||||
/* ************************************************************************* */
|
|
@ -20,54 +20,55 @@
|
|||
#include <gtsam/base/cholesky.h>
|
||||
#include <CppUnitLite/TestHarness.h>
|
||||
|
||||
#include <boost/numeric/ublas/triangular.hpp>
|
||||
#include <boost/numeric/ublas/matrix_proxy.hpp>
|
||||
#include <boost/numeric/ublas/symmetric.hpp>
|
||||
//#include <boost/numeric/ublas/triangular.hpp>
|
||||
//#include <boost/numeric/ublas/matrix_proxy.hpp>
|
||||
//#include <boost/numeric/ublas/symmetric.hpp>
|
||||
|
||||
using namespace gtsam;
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
//namespace ublas = boost::numeric::ublas;
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST(cholesky, cholesky_inplace) {
|
||||
Matrix I = Matrix_(5,5,
|
||||
1.739214152118470, 0.714164147286383, 1.893437990040579, 1.469485110232169, 1.549910412077052,
|
||||
0.714164147286383, 0.587767128354794, 0.738548568260523, 0.588775778746414, 0.645015863153235,
|
||||
1.893437990040579, 0.738548568260523, 2.165530165155413, 1.631203698494913, 1.617901992621506,
|
||||
1.469485110232169, 0.588775778746414, 1.631203698494913, 1.591363675348797, 1.584779118350080,
|
||||
1.549910412077052, 0.645015863153235, 1.617901992621506, 1.584779118350080, 1.928887183904716);
|
||||
///* ************************************************************************* */
|
||||
//TEST(cholesky, cholesky_inplace) {
|
||||
// Matrix I = Matrix_(5,5,
|
||||
// 1.739214152118470, 0.714164147286383, 1.893437990040579, 1.469485110232169, 1.549910412077052,
|
||||
// 0.714164147286383, 0.587767128354794, 0.738548568260523, 0.588775778746414, 0.645015863153235,
|
||||
// 1.893437990040579, 0.738548568260523, 2.165530165155413, 1.631203698494913, 1.617901992621506,
|
||||
// 1.469485110232169, 0.588775778746414, 1.631203698494913, 1.591363675348797, 1.584779118350080,
|
||||
// 1.549910412077052, 0.645015863153235, 1.617901992621506, 1.584779118350080, 1.928887183904716);
|
||||
//
|
||||
// Matrix expected = Matrix_(5,5,
|
||||
// 1.318792687316119, 0.541528743793524, 1.435735888021887, 1.114265437142152, 1.175249473995251,
|
||||
// 0.0, 0.542691208699940, -0.071760299365346, -0.026960052875681, 0.015818372803848,
|
||||
// 0.0, 0.0, 0.314711112667495, 0.093667363355578, -0.217058504307151,
|
||||
// 0.0, 0.0, 0.0, 0.583331630832890, 0.507424929100112,
|
||||
// 0.0, 0.0, 0.0, 0.0, 0.492779041656733);
|
||||
//
|
||||
// MatrixColMajor actualColMaj = I;
|
||||
// cholesky_inplace(actualColMaj);
|
||||
// Matrix actual = ublas::triangular_adaptor<MatrixColMajor, ublas::upper>(actualColMaj);
|
||||
// CHECK(assert_equal(expected, actual, 1e-7));
|
||||
//}
|
||||
|
||||
Matrix expected = Matrix_(5,5,
|
||||
1.318792687316119, 0.541528743793524, 1.435735888021887, 1.114265437142152, 1.175249473995251,
|
||||
0.0, 0.542691208699940, -0.071760299365346, -0.026960052875681, 0.015818372803848,
|
||||
0.0, 0.0, 0.314711112667495, 0.093667363355578, -0.217058504307151,
|
||||
0.0, 0.0, 0.0, 0.583331630832890, 0.507424929100112,
|
||||
0.0, 0.0, 0.0, 0.0, 0.492779041656733);
|
||||
|
||||
MatrixColMajor actualColMaj = I;
|
||||
cholesky_inplace(actualColMaj);
|
||||
Matrix actual = ublas::triangular_adaptor<MatrixColMajor, ublas::upper>(actualColMaj);
|
||||
CHECK(assert_equal(expected, actual, 1e-7));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST(cholesky, choleskyFactorUnderdetermined) {
|
||||
|
||||
Matrix Ab = Matrix_(3,7,
|
||||
0.0357, 0.6787, 0.3922, 0.7060, 0.0462, 0.6948, 0.0344,
|
||||
0.8491, 0.7577, 0.6555, 0.0318, 0.0971, 0.3171, 0.4387,
|
||||
0.9340, 0.7431, 0.1712, 0.2769, 0.8235, 0.9502, 0.3816);
|
||||
|
||||
Matrix expected = Matrix_(3,7,
|
||||
1.2628, 1.0784, 0.5785, 0.2462, 0.6757, 0.9357, 0.5782,
|
||||
0.0, 0.6513, 0.4089, 0.6811, -0.0180, 0.6280, 0.0244,
|
||||
0.0, 0.0, 0.3332, -0.2273, -0.4825, -0.4652, 0.0660);
|
||||
|
||||
MatrixColMajor actualColmaj = Ab;
|
||||
choleskyFactorUnderdetermined(actualColmaj, 3);
|
||||
Matrix actual = ublas::triangular_adaptor<MatrixColMajor, ublas::upper>(actualColmaj);
|
||||
|
||||
CHECK(assert_equal(expected, actual, 1e-3));
|
||||
}
|
||||
///* ************************************************************************* */
|
||||
//TEST(cholesky, choleskyFactorUnderdetermined) {
|
||||
//
|
||||
// Matrix Ab = Matrix_(3,7,
|
||||
// 0.0357, 0.6787, 0.3922, 0.7060, 0.0462, 0.6948, 0.0344,
|
||||
// 0.8491, 0.7577, 0.6555, 0.0318, 0.0971, 0.3171, 0.4387,
|
||||
// 0.9340, 0.7431, 0.1712, 0.2769, 0.8235, 0.9502, 0.3816);
|
||||
//
|
||||
// Matrix expected = Matrix_(3,7,
|
||||
// 1.2628, 1.0784, 0.5785, 0.2462, 0.6757, 0.9357, 0.5782,
|
||||
// 0.0, 0.6513, 0.4089, 0.6811, -0.0180, 0.6280, 0.0244,
|
||||
// 0.0, 0.0, 0.3332, -0.2273, -0.4825, -0.4652, 0.0660);
|
||||
//
|
||||
// MatrixColMajor actualColmaj = Ab;
|
||||
// choleskyFactorUnderdetermined(actualColmaj, 3);
|
||||
//
|
||||
// Matrix actual = ublas::triangular_adaptor<MatrixColMajor, ublas::upper>(actualColmaj);
|
||||
//
|
||||
// CHECK(assert_equal(expected, actual, 1e-3));
|
||||
//}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST(cholesky, choleskyPartial) {
|
||||
|
@ -88,15 +89,20 @@ TEST(cholesky, choleskyPartial) {
|
|||
choleskyPartial(RSL, 3);
|
||||
|
||||
// See the function comment for choleskyPartial, this decomposition should hold.
|
||||
Matrix R1(ublas::trans(RSL));
|
||||
Matrix R2(RSL);
|
||||
ublas::project(R1, ublas::range(3,7), ublas::range(3,7)) = eye(4,4);
|
||||
ublas::project(R2, ublas::range(3,7), ublas::range(3,7)) =
|
||||
ublas::symmetric_adaptor<const ublas::matrix_range<Matrix>,ublas::upper>(
|
||||
ublas::project(R2, ublas::range(3,7), ublas::range(3,7)));
|
||||
Matrix actual(R1 * R2);
|
||||
MatrixColMajor R1 = RSL.transpose();
|
||||
MatrixColMajor R2 = RSL;
|
||||
// ublas::project(R1, ublas::range(3,7), ublas::range(3,7)) = eye(4,4);
|
||||
R1.block(3, 3, 4, 4).setIdentity();
|
||||
|
||||
EXPECT(assert_equal(ublas::symmetric_adaptor<Matrix,ublas::upper>(ABC), actual, 1e-9));
|
||||
// ublas::project(R2, ublas::range(3,7), ublas::range(3,7)) =
|
||||
// ublas::symmetric_adaptor<const ublas::matrix_range<Matrix>,ublas::upper>(
|
||||
// ublas::project(R2, ublas::range(3,7), ublas::range(3,7)));
|
||||
R2.block(3, 3, 4, 4) = R2.block(3, 3, 4, 4).selfadjointView<Eigen::Upper>();
|
||||
|
||||
MatrixColMajor actual = R1 * R2;
|
||||
|
||||
MatrixColMajor expected = ABC.selfadjointView<Eigen::Upper>();
|
||||
EXPECT(assert_equal(expected, actual, 1e-9));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#include <CppUnitLite/TestHarness.h>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/numeric/ublas/matrix_proxy.hpp>
|
||||
#include <boost/numeric/ublas/io.hpp>
|
||||
#include <gtsam/base/Matrix.h>
|
||||
|
||||
using namespace std;
|
||||
|
@ -50,7 +48,7 @@ TEST( matrix, constructor_vector )
|
|||
double data[] = { -5, 3, 0, -5 };
|
||||
Matrix A = Matrix_(2, 2, data);
|
||||
Vector v(4);
|
||||
copy(data, data + 4, v.begin());
|
||||
copy(data, data + 4, v.data());
|
||||
Matrix B = Matrix_(2, 2, v); // this one is column order !
|
||||
EQUALITY(A,trans(B));
|
||||
}
|
||||
|
@ -74,10 +72,10 @@ TEST( matrix, row_major )
|
|||
{
|
||||
Matrix A = Matrix_(2, 2, 1.0, 2.0, 3.0, 4.0);
|
||||
const double * const a = &A(0, 0);
|
||||
CHECK(a[0] == 1);
|
||||
CHECK(a[1] == 2);
|
||||
CHECK(a[2] == 3);
|
||||
CHECK(a[3] == 4);
|
||||
EXPECT(a[0] == 1);
|
||||
EXPECT(a[1] == 2);
|
||||
EXPECT(a[2] == 3);
|
||||
EXPECT(a[3] == 4);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -95,7 +93,6 @@ TEST( matrix, collect1 )
|
|||
C(i, j + 2) = B(i, j);
|
||||
|
||||
EQUALITY(C,AB);
|
||||
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -116,7 +113,6 @@ TEST( matrix, collect2 )
|
|||
C(i, j + 2) = B(i, j);
|
||||
|
||||
EQUALITY(C,AB);
|
||||
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -129,8 +125,9 @@ TEST( matrix, collect3 )
|
|||
matrices.push_back(&A);
|
||||
matrices.push_back(&B);
|
||||
Matrix AB = collect(matrices, 2, 3);
|
||||
Matrix exp = Matrix_(2, 6, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
|
||||
0.0, 1.0, 0.0);
|
||||
Matrix exp = Matrix_(2, 6,
|
||||
1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0, 1.0, 0.0);
|
||||
|
||||
EQUALITY(exp,AB);
|
||||
}
|
||||
|
@ -158,17 +155,17 @@ TEST( matrix, column )
|
|||
Matrix A = Matrix_(4, 7, -1., 0., 1., 0., 0., 0., -0.2, 0., -1., 0., 1.,
|
||||
0., 0., 0.3, 1., 0., 0., 0., -1., 0., 0.2, 0., 1., 0., 0., 0., -1.,
|
||||
-0.1);
|
||||
Vector a1 = column_(A, 0);
|
||||
Vector a1 = column(A, 0);
|
||||
Vector exp1 = Vector_(4, -1., 0., 1., 0.);
|
||||
CHECK(assert_equal(a1, exp1));
|
||||
EXPECT(assert_equal(a1, exp1));
|
||||
|
||||
Vector a2 = column_(A, 3);
|
||||
Vector a2 = column(A, 3);
|
||||
Vector exp2 = Vector_(4, 0., 1., 0., 0.);
|
||||
CHECK(assert_equal(a2, exp2));
|
||||
EXPECT(assert_equal(a2, exp2));
|
||||
|
||||
Vector a3 = column_(A, 6);
|
||||
Vector a3 = column(A, 6);
|
||||
Vector exp3 = Vector_(4, -0.2, 0.3, 0.2, -0.1);
|
||||
CHECK(assert_equal(a3, exp3));
|
||||
EXPECT(assert_equal(a3, exp3));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -187,7 +184,7 @@ TEST( matrix, insert_column )
|
|||
0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||
|
||||
CHECK(assert_equal(expected, big));
|
||||
EXPECT(assert_equal(expected, big));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -210,7 +207,7 @@ TEST( matrix, insert_subcolumn )
|
|||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
CHECK(assert_equal(expected, big));
|
||||
EXPECT(assert_equal(expected, big));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -219,17 +216,17 @@ TEST( matrix, row )
|
|||
Matrix A = Matrix_(4, 7, -1., 0., 1., 0., 0., 0., -0.2, 0., -1., 0., 1.,
|
||||
0., 0., 0.3, 1., 0., 0., 0., -1., 0., 0.2, 0., 1., 0., 0., 0., -1.,
|
||||
-0.1);
|
||||
Vector a1 = row_(A, 0);
|
||||
Vector a1 = row(A, 0);
|
||||
Vector exp1 = Vector_(7, -1., 0., 1., 0., 0., 0., -0.2);
|
||||
CHECK(assert_equal(a1, exp1));
|
||||
EXPECT(assert_equal(a1, exp1));
|
||||
|
||||
Vector a2 = row_(A, 2);
|
||||
Vector a2 = row(A, 2);
|
||||
Vector exp2 = Vector_(7, 1., 0., 0., 0., -1., 0., 0.2);
|
||||
CHECK(assert_equal(a2, exp2));
|
||||
EXPECT(assert_equal(a2, exp2));
|
||||
|
||||
Vector a3 = row_(A, 3);
|
||||
Vector a3 = row(A, 3);
|
||||
Vector exp3 = Vector_(7, 0., 1., 0., 0., 0., -1., -0.1);
|
||||
CHECK(assert_equal(a3, exp3));
|
||||
EXPECT(assert_equal(a3, exp3));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -260,7 +257,7 @@ TEST( matrix, insert_sub )
|
|||
1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
CHECK(assert_equal(expected, big));
|
||||
EXPECT(assert_equal(expected, big));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -298,7 +295,7 @@ TEST( matrix, scale_columns )
|
|||
expected(2, 2) = 4.;
|
||||
expected(2, 3) = 5.;
|
||||
|
||||
CHECK(assert_equal(actual, expected));
|
||||
EXPECT(assert_equal(actual, expected));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -336,7 +333,7 @@ TEST( matrix, scale_rows )
|
|||
expected(2, 2) = 4.;
|
||||
expected(2, 3) = 4.;
|
||||
|
||||
CHECK(assert_equal(actual, expected));
|
||||
EXPECT(assert_equal(actual, expected));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -365,8 +362,8 @@ TEST( matrix, equal )
|
|||
Matrix A3(A);
|
||||
A3(3, 3) = -2.1;
|
||||
|
||||
CHECK(A==A2);
|
||||
CHECK(A!=A3);
|
||||
EXPECT(A==A2);
|
||||
EXPECT(A!=A3);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -395,7 +392,7 @@ TEST( matrix, equal_nan )
|
|||
Matrix A3(A);
|
||||
A3(3, 3) = inf;
|
||||
|
||||
CHECK(A!=A3);
|
||||
EXPECT(A!=A3);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -494,8 +491,8 @@ TEST( matrix, matrix_vector_multiplication )
|
|||
TEST( matrix, nrRowsAndnrCols )
|
||||
{
|
||||
Matrix A(3, 6);
|
||||
LONGS_EQUAL( A.size1() , 3 );
|
||||
LONGS_EQUAL( A.size2() , 6 );
|
||||
LONGS_EQUAL( A.rows() , 3 );
|
||||
LONGS_EQUAL( A.cols() , 6 );
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -516,6 +513,61 @@ TEST( matrix, scalar_divide )
|
|||
EQUALITY(B,A/10);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( matrix, zero_below_diagonal ) {
|
||||
Matrix A1 = Matrix_(3, 4,
|
||||
1.0, 2.0, 3.0, 4.0,
|
||||
1.0, 2.0, 3.0, 4.0,
|
||||
1.0, 2.0, 3.0, 4.0);
|
||||
|
||||
Matrix expected1 = Matrix_(3, 4,
|
||||
1.0, 2.0, 3.0, 4.0,
|
||||
0.0, 2.0, 3.0, 4.0,
|
||||
0.0, 0.0, 3.0, 4.0);
|
||||
Matrix actual1r = A1;
|
||||
zeroBelowDiagonal(actual1r);
|
||||
EXPECT(assert_equal(expected1, actual1r, 1e-10));
|
||||
|
||||
MatrixColMajor actual1c = A1;
|
||||
zeroBelowDiagonal(actual1c);
|
||||
EXPECT(assert_equal(MatrixColMajor(expected1), actual1c, 1e-10));
|
||||
|
||||
actual1c = A1;
|
||||
zeroBelowDiagonal(actual1c, 4);
|
||||
EXPECT(assert_equal(MatrixColMajor(expected1), actual1c, 1e-10));
|
||||
|
||||
Matrix A2 = Matrix_(5, 3,
|
||||
1.0, 2.0, 3.0,
|
||||
1.0, 2.0, 3.0,
|
||||
1.0, 2.0, 3.0,
|
||||
1.0, 2.0, 3.0,
|
||||
1.0, 2.0, 3.0);
|
||||
Matrix expected2 = Matrix_(5, 3,
|
||||
1.0, 2.0, 3.0,
|
||||
0.0, 2.0, 3.0,
|
||||
0.0, 0.0, 3.0,
|
||||
0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0);
|
||||
|
||||
Matrix actual2r = A2;
|
||||
zeroBelowDiagonal(actual2r);
|
||||
EXPECT(assert_equal(expected2, actual2r, 1e-10));
|
||||
|
||||
MatrixColMajor actual2c = A2;
|
||||
zeroBelowDiagonal(actual2c);
|
||||
EXPECT(assert_equal(MatrixColMajor(expected2), actual2c, 1e-10));
|
||||
|
||||
Matrix expected2_partial = Matrix_(5, 3,
|
||||
1.0, 2.0, 3.0,
|
||||
0.0, 2.0, 3.0,
|
||||
0.0, 2.0, 3.0,
|
||||
0.0, 2.0, 3.0,
|
||||
0.0, 2.0, 3.0);
|
||||
actual2c = A2;
|
||||
zeroBelowDiagonal(actual2c, 1);
|
||||
EXPECT(assert_equal(MatrixColMajor(expected2_partial), actual2c, 1e-10));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( matrix, inverse )
|
||||
{
|
||||
|
@ -531,8 +583,8 @@ TEST( matrix, inverse )
|
|||
A(2, 2) = 6;
|
||||
|
||||
Matrix Ainv = inverse(A);
|
||||
CHECK(assert_equal(eye(3), A*Ainv));
|
||||
CHECK(assert_equal(eye(3), Ainv*A));
|
||||
EXPECT(assert_equal(eye(3), A*Ainv));
|
||||
EXPECT(assert_equal(eye(3), Ainv*A));
|
||||
|
||||
Matrix expected(3, 3);
|
||||
expected(0, 0) = 1.0909;
|
||||
|
@ -545,21 +597,21 @@ TEST( matrix, inverse )
|
|||
expected(2, 1) = 0.0909;
|
||||
expected(2, 2) = 0.1818;
|
||||
|
||||
CHECK(assert_equal(expected, Ainv, 1e-4));
|
||||
EXPECT(assert_equal(expected, Ainv, 1e-4));
|
||||
|
||||
// These two matrices failed before version 2003 because we called LU incorrectly
|
||||
Matrix lMg(Matrix_(3, 3, 0.0, 1.0, -2.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0));
|
||||
CHECK(assert_equal(Matrix_(3,3,
|
||||
0.0, -1.0, 1.0,
|
||||
1.0, 0.0, 2.0,
|
||||
0.0, 0.0, 1.0),
|
||||
inverse(lMg)));
|
||||
EXPECT(assert_equal(Matrix_(3,3,
|
||||
0.0, -1.0, 1.0,
|
||||
1.0, 0.0, 2.0,
|
||||
0.0, 0.0, 1.0),
|
||||
inverse(lMg)));
|
||||
Matrix gMl(Matrix_(3, 3, 0.0, -1.0, 1.0, 1.0, 0.0, 2.0, 0.0, 0.0, 1.0));
|
||||
CHECK(assert_equal(Matrix_(3,3,
|
||||
0.0, 1.0,-2.0,
|
||||
-1.0, 0.0, 1.0,
|
||||
0.0, 0.0, 1.0),
|
||||
inverse(gMl)));
|
||||
EXPECT(assert_equal(Matrix_(3,3,
|
||||
0.0, 1.0,-2.0,
|
||||
-1.0, 0.0, 1.0,
|
||||
0.0, 0.0, 1.0),
|
||||
inverse(gMl)));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -589,7 +641,7 @@ TEST( matrix, inverse2 )
|
|||
expected(2, 1) = 0;
|
||||
expected(2, 2) = 1;
|
||||
|
||||
CHECK(assert_equal(expected, Ainv, 1e-4));
|
||||
EXPECT(assert_equal(expected, Ainv, 1e-4));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -599,78 +651,137 @@ TEST( matrix, backsubtitution )
|
|||
Vector expected1 = Vector_(2, 3.6250, -0.75);
|
||||
Matrix U22 = Matrix_(2, 2, 2., 3., 0., 4.);
|
||||
Vector b1 = U22 * expected1;
|
||||
CHECK( assert_equal(expected1 , backSubstituteUpper(U22, b1), 0.000001));
|
||||
EXPECT( assert_equal(expected1 , backSubstituteUpper(U22, b1), 0.000001));
|
||||
|
||||
// TEST TWO 3x3 matrix U2*x=b2
|
||||
Vector expected2 = Vector_(3, 5.5, -8.5, 5.);
|
||||
Matrix U33 = Matrix_(3, 3, 3., 5., 6., 0., 2., 3., 0., 0., 1.);
|
||||
Vector b2 = U33 * expected2;
|
||||
CHECK( assert_equal(expected2 , backSubstituteUpper(U33, b2), 0.000001));
|
||||
EXPECT( assert_equal(expected2 , backSubstituteUpper(U33, b2), 0.000001));
|
||||
|
||||
// TEST THREE Lower triangular 3x3 matrix L3*x=b3
|
||||
Vector expected3 = Vector_(3, 1., 1., 1.);
|
||||
Matrix L3 = trans(U33);
|
||||
Vector b3 = L3 * expected3;
|
||||
CHECK( assert_equal(expected3 , backSubstituteLower(L3, b3), 0.000001));
|
||||
EXPECT( assert_equal(expected3 , backSubstituteLower(L3, b3), 0.000001));
|
||||
|
||||
// TEST FOUR Try the above with transpose backSubstituteUpper
|
||||
CHECK( assert_equal(expected3 , backSubstituteUpper(b3,U33), 0.000001));
|
||||
EXPECT( assert_equal(expected3 , backSubstituteUpper(b3,U33), 0.000001));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
// unit tests for housholder transformation
|
||||
/* ************************************************************************* */
|
||||
TEST( matrix, houseHolder )
|
||||
TEST( matrix, householder )
|
||||
{
|
||||
double data[] = { -5, 0, 5, 0, 0, 0, -1,
|
||||
00,-5, 0, 5, 0, 0, 1.5,
|
||||
10, 0, 0, 0,-10,0, 2,
|
||||
00, 10,0, 0, 0, -10, -1 };
|
||||
00,-5, 0, 5, 0, 0, 1.5,
|
||||
10, 0, 0, 0,-10,0, 2,
|
||||
00, 10,0, 0, 0, -10, -1 };
|
||||
|
||||
// check in-place householder, with v vectors below diagonal
|
||||
double data1[] = { 11.1803, 0, -2.2361, 0, -8.9443, 0, 2.236,
|
||||
0, 11.1803, 0, -2.2361, 0, -8.9443, -1.565,
|
||||
-0.618034, 0, 4.4721, 0, -4.4721, 0, 0,
|
||||
0, -0.618034, 0, 4.4721, 0, -4.4721, 0.894 };
|
||||
double data1[] = {
|
||||
11.1803, 0, -2.2361, 0, -8.9443, 0, 2.236,
|
||||
0, 11.1803, 0, -2.2361, 0, -8.9443, -1.565,
|
||||
-0.618034, 0, 4.4721, 0, -4.4721, 0, 0,
|
||||
0, -0.618034, 0, 4.4721, 0, -4.4721, 0.894 };
|
||||
Matrix expected1 = Matrix_(4, 7, data1);
|
||||
Matrix A1 = Matrix_(4, 7, data);
|
||||
householder_(A1, 3);
|
||||
CHECK(assert_equal(expected1, A1, 1e-3));
|
||||
EXPECT(assert_equal(expected1, A1, 1e-3));
|
||||
|
||||
// in-place, with zeros below diagonal
|
||||
double data2[] = { 11.1803, 0, -2.2361, 0, -8.9443, 0, 2.236, 0, 11.1803,
|
||||
double data2[] = {
|
||||
11.1803, 0, -2.2361, 0, -8.9443, 0, 2.236, 0, 11.1803,
|
||||
0, -2.2361, 0, -8.9443, -1.565, 0, 0, 4.4721, 0, -4.4721, 0, 0, 0,
|
||||
0, 0, 4.4721, 0, -4.4721, 0.894 };
|
||||
Matrix expected = Matrix_(4, 7, data2);
|
||||
Matrix A2 = Matrix_(4, 7, data);
|
||||
householder(A2, 3);
|
||||
CHECK(assert_equal(expected, A2, 1e-3));
|
||||
EXPECT(assert_equal(expected, A2, 1e-3));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
// unit tests for housholder transformation
|
||||
/* ************************************************************************* */
|
||||
#ifdef GT_USE_LAPACK
|
||||
#ifdef YA_BLAS
|
||||
TEST( matrix, houseHolder2 )
|
||||
TEST( matrix, householder_colMajor )
|
||||
{
|
||||
double data[] = { -5, 0, 5, 0, 0, 0, -1,
|
||||
00,-5, 0, 5, 0, 0, 1.5,
|
||||
10, 0, 0, 0,-10,0, 2,
|
||||
00, 10,0, 0, 0, -10, -1 };
|
||||
double data[] = {
|
||||
-5, 0, 5, 0, 0, 0, -1,
|
||||
00,-5, 0, 5, 0, 0, 1.5,
|
||||
10, 0, 0, 0,-10,0, 2,
|
||||
00, 10,0, 0, 0, -10, -1 };
|
||||
|
||||
// check in-place householder, with v vectors below diagonal
|
||||
double data1[] = { 11.1803, 0, -2.2361, 0, -8.9443, 0, 2.236,
|
||||
0, 11.1803, 0, -2.2361, 0, -8.9443, -1.565,
|
||||
0, 0, 4.4721, 0, -4.4721, 0, 0,
|
||||
0, 0, 0, 4.4721, 0, -4.4721, 0.894 };
|
||||
Matrix expected1 = Matrix_(4, 7, data1);
|
||||
Matrix A1 = Matrix_(4, 7, data);
|
||||
householder(A1);
|
||||
CHECK(assert_equal(expected1, A1, 1e-3));
|
||||
double data1[] = {
|
||||
11.1803, 0, -2.2361, 0, -8.9443, 0, 2.236,
|
||||
0, 11.1803, 0, -2.2361, 0, -8.9443, -1.565,
|
||||
-0.618034, 0, 4.4721, 0, -4.4721, 0, 0,
|
||||
0, -0.618034, 0, 4.4721, 0, -4.4721, 0.894 };
|
||||
MatrixColMajor expected1(Matrix_(4, 7, data1));
|
||||
MatrixColMajor A1(Matrix_(4, 7, data));
|
||||
householder_(A1, 3);
|
||||
EXPECT(assert_equal(expected1, A1, 1e-3));
|
||||
|
||||
// in-place, with zeros below diagonal
|
||||
double data2[] = {
|
||||
11.1803, 0, -2.2361, 0, -8.9443, 0, 2.236, 0, 11.1803,
|
||||
0, -2.2361, 0, -8.9443, -1.565, 0, 0, 4.4721, 0, -4.4721, 0, 0, 0,
|
||||
0, 0, 4.4721, 0, -4.4721, 0.894 };
|
||||
MatrixColMajor expected(Matrix_(4, 7, data2));
|
||||
MatrixColMajor A2(Matrix_(4, 7, data));
|
||||
householder(A2, 3);
|
||||
EXPECT(assert_equal(expected, A2, 1e-3));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( matrix, eigen_QR )
|
||||
{
|
||||
// use standard Eigen function to yield a non-in-place QR factorization
|
||||
double data[] = {
|
||||
-5, 0, 5, 0, 0, 0, -1,
|
||||
00,-5, 0, 5, 0, 0, 1.5,
|
||||
10, 0, 0, 0,-10,0, 2,
|
||||
00, 10,0, 0, 0, -10, -1 };
|
||||
|
||||
// in-place, with zeros below diagonal
|
||||
double data2[] = {
|
||||
11.1803, 0, -2.2361, 0, -8.9443, 0, 2.236, 0, 11.1803,
|
||||
0, -2.2361, 0, -8.9443, -1.565, 0, 0, 4.4721, 0, -4.4721, 0, 0, 0,
|
||||
0, 0, 4.4721, 0, -4.4721, 0.894 };
|
||||
MatrixColMajor expected(Matrix_(4, 7, data2));
|
||||
MatrixColMajor A(Matrix_(4, 7, data));
|
||||
MatrixColMajor actual = A.householderQr().matrixQR();
|
||||
zeroBelowDiagonal(actual);
|
||||
|
||||
EXPECT(assert_equal(expected, actual, 1e-3));
|
||||
|
||||
// use shiny new in place QR inside gtsam
|
||||
A = MatrixColMajor(Matrix_(4, 7, data));
|
||||
inplace_QR(A);
|
||||
EXPECT(assert_equal(expected, A, 1e-3));
|
||||
}
|
||||
|
||||
///* ************************************************************************* */
|
||||
//// unit tests for householder transformation
|
||||
///* ************************************************************************* */
|
||||
//#ifdef GT_USE_LAPACK
|
||||
//#ifdef YA_BLAS
|
||||
//TEST( matrix, houseHolder2 )
|
||||
//{
|
||||
// double data[] = { -5, 0, 5, 0, 0, 0, -1,
|
||||
// 00,-5, 0, 5, 0, 0, 1.5,
|
||||
// 10, 0, 0, 0,-10,0, 2,
|
||||
// 00, 10,0, 0, 0, -10, -1 };
|
||||
//
|
||||
// // check in-place householder, with v vectors below diagonal
|
||||
// double data1[] = { 11.1803, 0, -2.2361, 0, -8.9443, 0, 2.236,
|
||||
// 0, 11.1803, 0, -2.2361, 0, -8.9443, -1.565,
|
||||
// 0, 0, 4.4721, 0, -4.4721, 0, 0,
|
||||
// 0, 0, 0, 4.4721, 0, -4.4721, 0.894 };
|
||||
// Matrix expected1 = Matrix_(4, 7, data1);
|
||||
// Matrix A1 = Matrix_(4, 7, data);
|
||||
// householder(A1);
|
||||
// EXPECT(assert_equal(expected1, A1, 1e-3));
|
||||
//}
|
||||
//#endif
|
||||
//#endif
|
||||
|
||||
/* ************************************************************************* */
|
||||
// unit test for qr factorization (and hence householder)
|
||||
|
@ -694,9 +805,9 @@ TEST( matrix, qr )
|
|||
|
||||
Matrix Q, R;
|
||||
boost::tie(Q, R) = qr(A);
|
||||
CHECK(assert_equal(expectedQ, Q, 1e-4));
|
||||
CHECK(assert_equal(expectedR, R, 1e-4));
|
||||
CHECK(assert_equal(A, Q*R, 1e-14));
|
||||
EXPECT(assert_equal(expectedQ, Q, 1e-4));
|
||||
EXPECT(assert_equal(expectedR, R, 1e-4));
|
||||
EXPECT(assert_equal(A, Q*R, 1e-14));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -735,7 +846,7 @@ TEST( matrix, row_major_access )
|
|||
// __attribute__ ((noinline)) // uncomment to prevent inlining when profiling
|
||||
//static void updateAb(Matrix& A, Vector& b, int j, const Vector& a,
|
||||
// const Vector& r, double d) {
|
||||
// const size_t m = A.size1(), n = A.size2();
|
||||
// const size_t m = A.rows(), n = A.cols();
|
||||
// for (int i = 0; i < m; i++) { // update all rows
|
||||
// double ai = a(i);
|
||||
// b(i) -= ai * d;
|
||||
|
@ -774,12 +885,12 @@ TEST( matrix, weighted_elimination )
|
|||
|
||||
// unpack and verify
|
||||
i = 0;
|
||||
BOOST_FOREACH(boost::tie(r, di, sigma), solution)
|
||||
{ CHECK(assert_equal(r, row(expectedR, i))); // verify r
|
||||
DOUBLES_EQUAL(d(i), di, 1e-8); // verify d
|
||||
DOUBLES_EQUAL(newSigmas(i), sigma, 1e-5); // verify sigma
|
||||
i += 1;
|
||||
}
|
||||
BOOST_FOREACH(boost::tie(r, di, sigma), solution){
|
||||
EXPECT(assert_equal(r, expectedR.row(i))); // verify r
|
||||
DOUBLES_EQUAL(d(i), di, 1e-8); // verify d
|
||||
DOUBLES_EQUAL(newSigmas(i), sigma, 1e-5); // verify sigma
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -795,25 +906,25 @@ TEST( matrix, inverse_square_root )
|
|||
EQUALITY(expected,actual);
|
||||
EQUALITY(measurement_covariance,inverse(actual*actual));
|
||||
|
||||
// Randomly generated test. This test really requires inverse to
|
||||
// be working well; if it's not, there's the possibility of a
|
||||
// Randomly generated test. This test really requires inverse to
|
||||
// be working well; if it's not, there's the possibility of a
|
||||
// bug in inverse masking a bug in this routine since we
|
||||
// use the same inverse routing inside inverse_square_root()
|
||||
// as we use here to check it.
|
||||
|
||||
Matrix M = Matrix_(5, 5,
|
||||
0.0785892, 0.0137923, -0.0142219, -0.0171880, 0.0028726,
|
||||
0.0137923, 0.0908911, 0.0020775, -0.0101952, 0.0175868,
|
||||
-0.0142219, 0.0020775, 0.0973051, 0.0054906, 0.0047064,
|
||||
-0.0171880,-0.0101952, 0.0054906, 0.0892453, -0.0059468,
|
||||
0.0028726, 0.0175868, 0.0047064, -0.0059468, 0.0816517);
|
||||
Matrix M = Matrix_(5, 5,
|
||||
0.0785892, 0.0137923, -0.0142219, -0.0171880, 0.0028726,
|
||||
0.0137923, 0.0908911, 0.0020775, -0.0101952, 0.0175868,
|
||||
-0.0142219, 0.0020775, 0.0973051, 0.0054906, 0.0047064,
|
||||
-0.0171880,-0.0101952, 0.0054906, 0.0892453, -0.0059468,
|
||||
0.0028726, 0.0175868, 0.0047064, -0.0059468, 0.0816517);
|
||||
|
||||
expected = trans(Matrix_(5, 5,
|
||||
3.567126953241796, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000,
|
||||
-0.590030436566913, 3.362022286742925, 0.000000000000000, 0.000000000000000, 0.000000000000000,
|
||||
0.618207860252376, -0.168166020746503, 3.253086082942785, 0.000000000000000, 0.000000000000000,
|
||||
0.683045380655496, 0.283773848115276, -0.099969232183396, 3.433537147891568, 0.000000000000000,
|
||||
-0.006740136923185, -0.669325697387650, -0.169716689114923, 0.171493059476284, 3.583921085468937));
|
||||
3.567126953241796, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000,
|
||||
-0.590030436566913, 3.362022286742925, 0.000000000000000, 0.000000000000000, 0.000000000000000,
|
||||
0.618207860252376, -0.168166020746503, 3.253086082942785, 0.000000000000000, 0.000000000000000,
|
||||
0.683045380655496, 0.283773848115276, -0.099969232183396, 3.433537147891568, 0.000000000000000,
|
||||
-0.006740136923185, -0.669325697387650, -0.169716689114923, 0.171493059476284, 3.583921085468937));
|
||||
EQUALITY(expected, inverse_square_root(M));
|
||||
|
||||
}
|
||||
|
@ -830,11 +941,11 @@ TEST( matrix, LLt )
|
|||
-0.0021113, 0.0036415, 0.0909464);
|
||||
|
||||
Matrix expected = Matrix_(5, 5,
|
||||
0.295668226226627, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000,
|
||||
-0.010437374483502, 0.295235094820875, 0.000000000000000, 0.000000000000000, 0.000000000000000,
|
||||
0.039560896175007, 0.063407813693827, 0.301721866387571, 0.000000000000000, 0.000000000000000,
|
||||
0.027552165831157, 0.043423266737274, 0.021695600982708, 0.267613525371710, 0.000000000000000,
|
||||
0.016485031422565, -0.012072546984405, -0.006621889326331, 0.014405837566082, 0.300462176944247);
|
||||
0.295668226226627, 0.000000000000000, 0.000000000000000, 0.000000000000000, 0.000000000000000,
|
||||
-0.010437374483502, 0.295235094820875, 0.000000000000000, 0.000000000000000, 0.000000000000000,
|
||||
0.039560896175007, 0.063407813693827, 0.301721866387571, 0.000000000000000, 0.000000000000000,
|
||||
0.027552165831157, 0.043423266737274, 0.021695600982708, 0.267613525371710, 0.000000000000000,
|
||||
0.016485031422565, -0.012072546984405, -0.006621889326331, 0.014405837566082, 0.300462176944247);
|
||||
|
||||
EQUALITY(expected, LLt(M));
|
||||
}
|
||||
|
@ -844,10 +955,10 @@ TEST( matrix, multiplyAdd )
|
|||
{
|
||||
Matrix A = Matrix_(3, 4, 4., 0., 0., 1., 0., 4., 0., 2., 0., 0., 1., 3.);
|
||||
Vector x = Vector_(4, 1., 2., 3., 4.), e = Vector_(3, 5., 6., 7.),
|
||||
expected = e + prod(A, x);
|
||||
expected = e + A * x;
|
||||
|
||||
multiplyAdd(1, A, x, e);
|
||||
CHECK(assert_equal(expected, e));
|
||||
EXPECT(assert_equal(expected, e));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -855,10 +966,10 @@ TEST( matrix, transposeMultiplyAdd )
|
|||
{
|
||||
Matrix A = Matrix_(3, 4, 4., 0., 0., 1., 0., 4., 0., 2., 0., 0., 1., 3.);
|
||||
Vector x = Vector_(4, 1., 2., 3., 4.), e = Vector_(3, 5., 6., 7.),
|
||||
expected = x + prod(trans(A), e);
|
||||
expected = x + trans(A) * e;
|
||||
|
||||
transposeMultiplyAdd(1, A, e, x);
|
||||
CHECK(assert_equal(expected, x));
|
||||
EXPECT(assert_equal(expected, x));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -866,7 +977,7 @@ TEST( matrix, linear_dependent )
|
|||
{
|
||||
Matrix A = Matrix_(2, 3, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
|
||||
Matrix B = Matrix_(2, 3, -1.0, -2.0, -3.0, 8.0, 10.0, 12.0);
|
||||
CHECK(linear_dependent(A, B));
|
||||
EXPECT(linear_dependent(A, B));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -874,7 +985,7 @@ TEST( matrix, linear_dependent2 )
|
|||
{
|
||||
Matrix A = Matrix_(2, 3, 0.0, 2.0, 3.0, 4.0, 5.0, 6.0);
|
||||
Matrix B = Matrix_(2, 3, 0.0, -2.0, -3.0, 8.0, 10.0, 12.0);
|
||||
CHECK(linear_dependent(A, B));
|
||||
EXPECT(linear_dependent(A, B));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -882,7 +993,97 @@ TEST( matrix, linear_dependent3 )
|
|||
{
|
||||
Matrix A = Matrix_(2, 3, 0.0, 2.0, 3.0, 4.0, 5.0, 6.0);
|
||||
Matrix B = Matrix_(2, 3, 0.0, -2.0, -3.0, 8.1, 10.0, 12.0);
|
||||
CHECK(linear_independent(A, B));
|
||||
EXPECT(linear_independent(A, B));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( matrix, svd1 )
|
||||
{
|
||||
Vector v = Vector_(3, 2., 1., 0.);
|
||||
Matrix U1 = eye(4, 3), S1 = diag(v), V1 = eye(3, 3), A = (U1 * S1)
|
||||
* Matrix(trans(V1));
|
||||
Matrix U, V;
|
||||
Vector s;
|
||||
svd(A, U, s, V);
|
||||
Matrix S = diag(s);
|
||||
EXPECT(assert_equal(U*S*Matrix(trans(V)),A));
|
||||
EXPECT(assert_equal(S,S1));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
/// Sample A matrix for SVD
|
||||
static Matrix sampleA = Matrix_(3, 2, 0.,-2., 0., 0., 3., 0.);
|
||||
static Matrix sampleAt = trans(sampleA);
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( matrix, svd2 )
|
||||
{
|
||||
Matrix U, V;
|
||||
Vector s;
|
||||
|
||||
Matrix expectedU = Matrix_(3, 2, 0.,1.,0.,0.,-1.,0.);
|
||||
Vector expected_s = Vector_(2, 3.,2.);
|
||||
Matrix expectedV = Matrix_(2, 2, -1.,0.,0.,-1.);
|
||||
|
||||
svd(sampleA, U, s, V);
|
||||
|
||||
EXPECT(assert_equal(expectedU,U));
|
||||
EXPECT(assert_equal(expected_s,s,1e-9));
|
||||
EXPECT(assert_equal(expectedV,V));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( matrix, svd3 )
|
||||
{
|
||||
Matrix U, V;
|
||||
Vector s;
|
||||
|
||||
Matrix expectedU = Matrix_(2, 2, -1.,0.,0.,-1.);
|
||||
Vector expected_s = Vector_(2, 3.0,2.0);
|
||||
Matrix expectedV = Matrix_(3, 2, 0.,1.,0.,0.,-1.,0.);
|
||||
|
||||
svd(sampleAt, U, s, V);
|
||||
Matrix S = diag(s);
|
||||
Matrix t = U * S;
|
||||
Matrix Vt = trans(V);
|
||||
|
||||
EXPECT(assert_equal(sampleAt, prod(t, Vt)));
|
||||
EXPECT(assert_equal(expectedU,U));
|
||||
EXPECT(assert_equal(expected_s,s,1e-9));
|
||||
EXPECT(assert_equal(expectedV,V));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( matrix, svd4 )
|
||||
{
|
||||
Matrix U, V;
|
||||
Vector s;
|
||||
|
||||
Matrix A = Matrix_(3,2,
|
||||
0.8147, 0.9134,
|
||||
0.9058, 0.6324,
|
||||
0.1270, 0.0975);
|
||||
|
||||
Matrix expectedU = Matrix_(3,2,
|
||||
/// right column - originally had opposite sign
|
||||
-0.7397, -0.6724,
|
||||
-0.6659, 0.7370,
|
||||
-0.0970, 0.0689);
|
||||
|
||||
Vector expected_s = Vector_(2, 1.6455, 0.1910);
|
||||
|
||||
Matrix expectedV = Matrix_(2,2,
|
||||
/// right column - originally had opposite sign
|
||||
-0.7403, 0.6723,
|
||||
-0.6723, -0.7403);
|
||||
|
||||
svd(A, U, s, V);
|
||||
Matrix reconstructed = U * diag(s) * trans(V);
|
||||
|
||||
EXPECT(assert_equal(A, reconstructed, 1e-4));
|
||||
EXPECT(assert_equal(expectedU,U, 1e-3));
|
||||
EXPECT(assert_equal(expected_s,s, 1e-4));
|
||||
EXPECT(assert_equal(expectedV,V, 1e-4));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
@ -30,7 +30,7 @@ double f(const LieVector& x) {
|
|||
|
||||
/* ************************************************************************* */
|
||||
TEST_UNSAFE(testNumericalDerivative, numericalHessian) {
|
||||
LieVector center(2, 1.0, 1.0);
|
||||
LieVector center = ones(2);
|
||||
|
||||
Matrix expected = Matrix_(2,2,
|
||||
-sin(center(0)), 0.0,
|
||||
|
|
|
@ -29,7 +29,7 @@ TEST( TestVector, Vector_variants )
|
|||
Vector a = Vector_(2,10.0,20.0);
|
||||
double data[] = {10,20};
|
||||
Vector b = Vector_(2,data);
|
||||
CHECK(a==b);
|
||||
EXPECT(assert_equal(a, b));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -37,23 +37,25 @@ TEST( TestVector, copy )
|
|||
{
|
||||
Vector a(2); a(0) = 10; a(1) = 20;
|
||||
double data[] = {10,20};
|
||||
Vector b(2); copy(data,data+2,b.begin());
|
||||
CHECK(a==b);
|
||||
Vector b(2);
|
||||
copy(data,data+2,b.data());
|
||||
EXPECT(assert_equal(a, b));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( TestVector, zero1 )
|
||||
{
|
||||
Vector v(2,0.0);
|
||||
CHECK(zero(v)==true);
|
||||
Vector v = Vector::Zero(2);
|
||||
EXPECT(zero(v));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( TestVector, zero2 )
|
||||
{
|
||||
Vector a = zero(2);
|
||||
Vector b(2,0.0);
|
||||
CHECK(a==b);
|
||||
Vector b = Vector::Zero(2);
|
||||
EXPECT(a==b);
|
||||
EXPECT(assert_equal(a, b));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -61,7 +63,7 @@ TEST( TestVector, scalar_multiply )
|
|||
{
|
||||
Vector a(2); a(0) = 10; a(1) = 20;
|
||||
Vector b(2); b(0) = 1; b(1) = 2;
|
||||
CHECK(a==b*10.0);
|
||||
EXPECT(assert_equal(a,b*10.0));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -69,7 +71,7 @@ TEST( TestVector, scalar_divide )
|
|||
{
|
||||
Vector a(2); a(0) = 10; a(1) = 20;
|
||||
Vector b(2); b(0) = 1; b(1) = 2;
|
||||
CHECK(b==a/10.0);
|
||||
EXPECT(assert_equal(b,a/10.0));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -77,22 +79,23 @@ TEST( TestVector, negate )
|
|||
{
|
||||
Vector a(2); a(0) = 10; a(1) = 20;
|
||||
Vector b(2); b(0) = -10; b(1) = -20;
|
||||
CHECK(b==-a);
|
||||
EXPECT(assert_equal(b, -a));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( TestVector, sub )
|
||||
{
|
||||
Vector a(6);
|
||||
a(0) = 10; a(1) = 20; a(2) = 3;
|
||||
a(0) = 10; a(1) = 20; a(2) = 3;
|
||||
a(3) = 34; a(4) = 11; a(5) = 2;
|
||||
|
||||
Vector result(sub(a,2,5));
|
||||
|
||||
Vector b(3);
|
||||
b(0) = 3; b(1) = 34; b(2) =11;
|
||||
|
||||
CHECK(b==result);
|
||||
Vector result(sub(a,2,5));
|
||||
|
||||
Vector b(3);
|
||||
b(0) = 3; b(1) = 34; b(2) =11;
|
||||
|
||||
EXPECT(b==result);
|
||||
EXPECT(assert_equal(b, result));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -106,30 +109,22 @@ TEST( TestVector, subInsert )
|
|||
|
||||
Vector expected = Vector_(6, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0);
|
||||
|
||||
CHECK(assert_equal(expected, big));
|
||||
EXPECT(assert_equal(expected, big));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( TestVector, householder )
|
||||
{
|
||||
Vector x(4);
|
||||
Vector x(4);
|
||||
x(0) = 3; x(1) = 1; x(2) = 5; x(3) = 1;
|
||||
|
||||
|
||||
Vector expected(4);
|
||||
expected(0) = 1.0; expected(1) = -0.333333; expected(2) = -1.66667; expected(3) = -0.333333;
|
||||
|
||||
pair<double, Vector> result = house(x);
|
||||
|
||||
CHECK(result.first==0.5);
|
||||
CHECK(equal_with_abs_tol(expected,result.second,1e-5));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( TestVector, zeros )
|
||||
{
|
||||
Vector a(2); a(0) = 0; a(1) = 0;
|
||||
Vector b(2,0.0);
|
||||
CHECK(b==a);
|
||||
pair<double, Vector> result = house(x);
|
||||
|
||||
EXPECT(result.first==0.5);
|
||||
EXPECT(equal_with_abs_tol(expected,result.second,1e-5));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -141,7 +136,7 @@ TEST( TestVector, concatVectors)
|
|||
Vector B(5);
|
||||
for(int i = 0; i < 5; i++)
|
||||
B(i) = i;
|
||||
|
||||
|
||||
Vector C(7);
|
||||
for(int i = 0; i < 2; i++) C(i) = A(i);
|
||||
for(int i = 0; i < 5; i++) C(i+2) = B(i);
|
||||
|
@ -150,10 +145,10 @@ TEST( TestVector, concatVectors)
|
|||
vs.push_back(A);
|
||||
vs.push_back(B);
|
||||
Vector AB1 = concatVectors(vs);
|
||||
CHECK(AB1 == C);
|
||||
EXPECT(AB1 == C);
|
||||
|
||||
Vector AB2 = concatVectors(2, &A, &B);
|
||||
CHECK(AB2 == C);
|
||||
EXPECT(AB2 == C);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -178,8 +173,8 @@ TEST( TestVector, weightedPseudoinverse )
|
|||
double expPrecision = 200.0;
|
||||
|
||||
// verify
|
||||
CHECK(assert_equal(expected,actual));
|
||||
CHECK(fabs(expPrecision-precision) < 1e-5);
|
||||
EXPECT(assert_equal(expected,actual));
|
||||
EXPECT(fabs(expPrecision-precision) < 1e-5);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -203,8 +198,8 @@ TEST( TestVector, weightedPseudoinverse_constraint )
|
|||
expected(0) = 1.0; expected(1) = 0.0;
|
||||
|
||||
// verify
|
||||
CHECK(assert_equal(expected,actual));
|
||||
CHECK(isinf(precision));
|
||||
EXPECT(assert_equal(expected,actual));
|
||||
EXPECT(isinf(precision));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -217,11 +212,10 @@ TEST( TestVector, weightedPseudoinverse_nan )
|
|||
boost::tie(pseudo, precision) = weightedPseudoinverse(a, weights);
|
||||
|
||||
Vector expected = Vector_(4, 1., 0., 0.,0.);
|
||||
CHECK(assert_equal(expected, pseudo));
|
||||
EXPECT(assert_equal(expected, pseudo));
|
||||
DOUBLES_EQUAL(100, precision, 1e-5);
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( TestVector, ediv )
|
||||
{
|
||||
|
@ -230,7 +224,7 @@ TEST( TestVector, ediv )
|
|||
Vector actual(ediv(a,b));
|
||||
|
||||
Vector c = Vector_(3,5.0,4.0,5.0);
|
||||
CHECK(assert_equal(c,actual));
|
||||
EXPECT(assert_equal(c,actual));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -248,7 +242,7 @@ TEST( TestVector, axpy )
|
|||
Vector y = Vector_(3,2.0,5.0,6.0);
|
||||
axpy(0.1,x,y);
|
||||
Vector expected = Vector_(3,3.0,7.0,9.0);
|
||||
CHECK(assert_equal(expected,y));
|
||||
EXPECT(assert_equal(expected,y));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -257,7 +251,7 @@ TEST( TestVector, equals )
|
|||
Vector v1 = Vector_(1, 0.0/0.0); //testing nan
|
||||
Vector v2 = Vector_(1, 1.0);
|
||||
double tol = 1.;
|
||||
CHECK(!equal_with_abs_tol(v1, v2, tol));
|
||||
EXPECT(!equal_with_abs_tol(v1, v2, tol));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -265,15 +259,15 @@ TEST( TestVector, greater_than )
|
|||
{
|
||||
Vector v1 = Vector_(3, 1.0, 2.0, 3.0),
|
||||
v2 = zero(3);
|
||||
CHECK(greaterThanOrEqual(v1, v1)); // test basic greater than
|
||||
CHECK(greaterThanOrEqual(v1, v2)); // test equals
|
||||
EXPECT(greaterThanOrEqual(v1, v1)); // test basic greater than
|
||||
EXPECT(greaterThanOrEqual(v1, v2)); // test equals
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
TEST( TestVector, reciprocal )
|
||||
{
|
||||
Vector v = Vector_(3, 1.0, 2.0, 4.0);
|
||||
CHECK(assert_equal(Vector_(3, 1.0, 0.5, 0.25),reciprocal(v)));
|
||||
EXPECT(assert_equal(Vector_(3, 1.0, 0.5, 0.25),reciprocal(v)));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -281,7 +275,7 @@ TEST( TestVector, linear_dependent )
|
|||
{
|
||||
Vector v1 = Vector_(3, 1.0, 2.0, 3.0);
|
||||
Vector v2 = Vector_(3, -2.0, -4.0, -6.0);
|
||||
CHECK(linear_dependent(v1, v2));
|
||||
EXPECT(linear_dependent(v1, v2));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -289,7 +283,7 @@ TEST( TestVector, linear_dependent2 )
|
|||
{
|
||||
Vector v1 = Vector_(3, 0.0, 2.0, 0.0);
|
||||
Vector v2 = Vector_(3, 0.0, -4.0, 0.0);
|
||||
CHECK(linear_dependent(v1, v2));
|
||||
EXPECT(linear_dependent(v1, v2));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -297,7 +291,7 @@ TEST( TestVector, linear_dependent3 )
|
|||
{
|
||||
Vector v1 = Vector_(3, 0.0, 2.0, 0.0);
|
||||
Vector v2 = Vector_(3, 0.1, -4.1, 0.0);
|
||||
CHECK(!linear_dependent(v1, v2));
|
||||
EXPECT(!linear_dependent(v1, v2));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
@ -162,7 +162,7 @@ double timeColumn(size_t reps) {
|
|||
for (size_t i=0; i<reps; ++i)
|
||||
for (size_t j = 0; j<n; ++j)
|
||||
//result = ublas::matrix_column<Matrix>(M, j);
|
||||
result = column_(M, j);
|
||||
result = column(M, j);
|
||||
elapsed = t.elapsed();
|
||||
}
|
||||
return elapsed;
|
||||
|
@ -257,8 +257,8 @@ int main(int argc, char ** argv) {
|
|||
double vsRow_time = timeVScaleRow(m1, n1, reps1);
|
||||
cout << "Elapsed time for vector_scale(row) [(" << m1 << ", " << n1 << ") matrix] : " << vsRow_time << endl;
|
||||
|
||||
// Time column_() NOTE: using the ublas version
|
||||
cout << "Starting column_() Timing" << endl;
|
||||
// Time column() NOTE: using the ublas version
|
||||
cout << "Starting column() Timing" << endl;
|
||||
size_t reps2 = 2000000;
|
||||
double column_time = timeColumn(reps2);
|
||||
cout << "Time: " << column_time << " sec" << endl;
|
||||
|
|
|
@ -93,7 +93,7 @@ Matrix Cal3Bundler::D2d_intrinsic(const Point2& p) const {
|
|||
Matrix DR = Matrix_(2, 2,
|
||||
g + x*dg_dx, x*dg_dy,
|
||||
y*dg_dx , g + y*dg_dy) ;
|
||||
return prod(DK,DR) ;
|
||||
return DK * DR;
|
||||
}
|
||||
|
||||
Matrix Cal3Bundler::D2d_calibration(const Point2& p) const {
|
||||
|
|
|
@ -92,7 +92,7 @@ Matrix Cal3DS2::D2d_intrinsic(const Point2& p) const {
|
|||
Matrix DR = Matrix_(2, 2, g + x*dg_dx + dDx_dx, x*dg_dy + dDx_dy,
|
||||
y*dg_dx + dDy_dx, g + y*dg_dy + dDy_dy) ;
|
||||
|
||||
return prod(DK,DR) ;
|
||||
return DK * DR;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ namespace gtsam {
|
|||
Vector vector() const {
|
||||
double r[] = { fx_, fy_, s_, u0_, v0_ };
|
||||
Vector v(5);
|
||||
copy(r, r + 5, v.begin());
|
||||
std::copy(r, r + 5, v.data());
|
||||
return v;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <boost/numeric/ublas/vector_proxy.hpp>
|
||||
#include <boost/numeric/ublas/matrix_proxy.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <gtsam/base/Vector.h>
|
||||
#include <gtsam/base/Matrix.h>
|
||||
|
@ -52,8 +50,8 @@ class GeneralCameraT {
|
|||
|
||||
// Vector Initialization
|
||||
GeneralCameraT(const Vector &v) :
|
||||
calibrated_(subrange(v, 0, Camera::Dim())),
|
||||
calibration_(subrange(v, Camera::Dim(), Camera::Dim() + Calibration::Dim() )) {}
|
||||
calibrated_(sub(v, 0, Camera::Dim())),
|
||||
calibration_(sub(v, Camera::Dim(), Camera::Dim() + Calibration::Dim() )) {}
|
||||
|
||||
inline const Pose3& pose() const { return calibrated_.pose(); }
|
||||
inline const Camera& calibrated() const { return calibrated_; }
|
||||
|
@ -123,8 +121,8 @@ class GeneralCameraT {
|
|||
}
|
||||
|
||||
GeneralCameraT expmap(const Vector &v) const {
|
||||
Vector v1 = subrange(v,0,Camera::Dim());
|
||||
Vector v2 = subrange(v,Camera::Dim(),Camera::Dim()+Calibration::Dim());
|
||||
Vector v1 = sub(v,0,Camera::Dim());
|
||||
Vector v2 = sub(v,Camera::Dim(),Camera::Dim()+Calibration::Dim());
|
||||
return GeneralCameraT(calibrated_.expmap(v1), calibration_.expmap(v2));
|
||||
}
|
||||
|
||||
|
@ -138,8 +136,8 @@ class GeneralCameraT {
|
|||
static GeneralCameraT Expmap(const Vector& v) {
|
||||
//std::cout << "Expmap" << std::endl;
|
||||
return GeneralCameraT(
|
||||
Camera::Expmap(subrange(v,0,Camera::Dim())),
|
||||
Calibration::Expmap(subrange(v,Camera::Dim(), Camera::Dim()+Calibration::Dim()))
|
||||
Camera::Expmap(sub(v,0,Camera::Dim())),
|
||||
Calibration::Expmap(sub(v,Camera::Dim(), Camera::Dim()+Calibration::Dim()))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -159,15 +157,15 @@ class GeneralCameraT {
|
|||
Point2 intrinsic = calibrated_.project(point);
|
||||
Matrix D_intrinsic_pose = Dproject_pose(calibrated_, point);
|
||||
Matrix D_2d_intrinsic = calibration_.D2d_intrinsic(intrinsic);
|
||||
Matrix D_2d_pose = prod(D_2d_intrinsic,D_intrinsic_pose);
|
||||
Matrix D_2d_pose = D_2d_intrinsic * D_intrinsic_pose;
|
||||
Matrix D_2d_calibration = calibration_.D2d_calibration(intrinsic);
|
||||
|
||||
const int n1 = calibrated_.dim() ;
|
||||
const int n2 = calibration_.dim() ;
|
||||
Matrix D(2,n1+n2) ;
|
||||
|
||||
subrange(D,0,2,0,n1) = D_2d_pose ;
|
||||
subrange(D,0,2,n1,n1+n2) = D_2d_calibration ;
|
||||
sub(D,0,2,0,n1) = D_2d_pose ;
|
||||
sub(D,0,2,n1,n1+n2) = D_2d_calibration ;
|
||||
return D;
|
||||
}
|
||||
|
||||
|
@ -175,27 +173,27 @@ class GeneralCameraT {
|
|||
Point2 intrinsic = calibrated_.project(point);
|
||||
Matrix D_intrinsic_3d = Dproject_point(calibrated_, point);
|
||||
Matrix D_2d_intrinsic = calibration_.D2d_intrinsic(intrinsic);
|
||||
return prod(D_2d_intrinsic,D_intrinsic_3d);
|
||||
return D_2d_intrinsic * D_intrinsic_3d;
|
||||
}
|
||||
|
||||
Matrix D2d_camera_3d(const Point3& point) const {
|
||||
Point2 intrinsic = calibrated_.project(point);
|
||||
Matrix D_intrinsic_pose = Dproject_pose(calibrated_, point);
|
||||
Matrix D_2d_intrinsic = calibration_.D2d_intrinsic(intrinsic);
|
||||
Matrix D_2d_pose = prod(D_2d_intrinsic,D_intrinsic_pose);
|
||||
Matrix D_2d_pose = D_2d_intrinsic * D_intrinsic_pose;
|
||||
Matrix D_2d_calibration = calibration_.D2d_calibration(intrinsic);
|
||||
|
||||
Matrix D_intrinsic_3d = Dproject_point(calibrated_, point);
|
||||
Matrix D_2d_3d = prod(D_2d_intrinsic,D_intrinsic_3d);
|
||||
Matrix D_2d_3d = D_2d_intrinsic * D_intrinsic_3d;
|
||||
|
||||
const int n1 = calibrated_.dim() ;
|
||||
const int n2 = calibration_.dim() ;
|
||||
|
||||
Matrix D(2,n1+n2+3) ;
|
||||
|
||||
subrange(D,0,2,0,n1) = D_2d_pose ;
|
||||
subrange(D,0,2,n1,n1+n2) = D_2d_calibration ;
|
||||
subrange(D,0,2,n1+n2,n1+n2+3) = D_2d_3d ;
|
||||
sub(D,0,2,0,n1) = D_2d_pose ;
|
||||
sub(D,0,2,n1,n1+n2) = D_2d_calibration ;
|
||||
sub(D,0,2,n1+n2,n1+n2+3) = D_2d_3d ;
|
||||
return D;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,10 +53,6 @@ AM_LDFLAGS += $(boost_serialization)
|
|||
LDADD = libgeometry.la ../base/libbase.la ../../CppUnitLite/libCppUnitLite.a
|
||||
AM_DEFAULT_SOURCE_EXT = .cpp
|
||||
|
||||
if USE_ACCELERATE_MACOS
|
||||
AM_LDFLAGS += -Wl,/System/Library/Frameworks/Accelerate.framework/Accelerate
|
||||
endif
|
||||
|
||||
# rule to run an executable
|
||||
%.run: % $(LDADD)
|
||||
./$^
|
||||
|
|
|
@ -190,7 +190,7 @@ namespace gtsam {
|
|||
-c, -s, dt1,
|
||||
s, -c, dt2,
|
||||
0.0, 0.0, -1.0};
|
||||
copy(data, data+9, H1->data().begin());
|
||||
copy(data, data+9, H1->data());
|
||||
}
|
||||
if (H2) *H2 = I3;
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace gtsam {
|
|||
|
||||
/** Constructor from 3*3 matrix */
|
||||
Pose2(const Matrix &T) :
|
||||
r_(Rot2::atan2(T(1, 0), T(0, 0))), t_(T(0, 2), T(1, 2)) { assert(T.size1()==3 && T.size2()==3); }
|
||||
r_(Rot2::atan2(T(1, 0), T(0, 0))), t_(T(0, 2), T(1, 2)) { assert(T.rows()==3 && T.cols()==3); }
|
||||
|
||||
/** print with optional string */
|
||||
void print(const std::string& s = "") const;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <gtsam/base/Lie-inl.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::numeric::ublas;
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
|
@ -77,7 +76,7 @@ namespace gtsam {
|
|||
/* ************************************************************************* */
|
||||
Vector Pose3::LogmapFull(const Pose3& p) {
|
||||
Vector w = Rot3::Logmap(p.rotation()), T = p.translation().vector();
|
||||
double t = norm_2(w);
|
||||
double t = w.norm();
|
||||
if (t < 1e-10)
|
||||
return concatVectors(2, &w, &T);
|
||||
else {
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <boost/numeric/ublas/vector_proxy.hpp>
|
||||
|
||||
#include <gtsam/geometry/Point3.h>
|
||||
#include <gtsam/geometry/Rot3.h>
|
||||
#include <gtsam/base/Testable.h>
|
||||
|
|
|
@ -104,7 +104,7 @@ namespace gtsam {
|
|||
|
||||
/* ************************************************************************* */
|
||||
Rot3 Rot3::rodriguez(const Vector& w) {
|
||||
double t = norm_2(w);
|
||||
double t = w.norm();
|
||||
if (t < 1e-10) return Rot3();
|
||||
return rodriguez(w/t, t);
|
||||
}
|
||||
|
|
|
@ -17,10 +17,7 @@
|
|||
*/
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/numeric/ublas/matrix.hpp>
|
||||
#include <boost/numeric/ublas/matrix_proxy.hpp>
|
||||
#include <gtsam/base/Matrix.h>
|
||||
typedef boost::numeric::ublas::matrix_row<Matrix> Row;
|
||||
|
||||
#include <gtsam/geometry/tensorInterface.h>
|
||||
#include <gtsam/geometry/projectiveGeometry.h>
|
||||
|
|
|
@ -43,8 +43,7 @@ TEST( Pose3, equals)
|
|||
TEST( Pose3, expmap_a)
|
||||
{
|
||||
Pose3 id;
|
||||
Vector v(6);
|
||||
fill(v.begin(), v.end(), 0);
|
||||
Vector v = zero(6);
|
||||
v(0) = 0.3;
|
||||
CHECK(assert_equal(id.expmap(v), Pose3(R, Point3())));
|
||||
#ifdef CORRECT_POSE3_EXMAP
|
||||
|
@ -60,8 +59,7 @@ TEST( Pose3, expmap_a)
|
|||
TEST( Pose3, expmap_a_full)
|
||||
{
|
||||
Pose3 id;
|
||||
Vector v(6);
|
||||
fill(v.begin(), v.end(), 0);
|
||||
Vector v = zero(6);
|
||||
v(0) = 0.3;
|
||||
CHECK(assert_equal(id.expmapFull(v), Pose3(R, Point3())));
|
||||
v(3)=0.2;v(4)=0.394742;v(5)=-2.08998;
|
||||
|
@ -72,8 +70,7 @@ TEST( Pose3, expmap_a_full)
|
|||
TEST( Pose3, expmap_a_full2)
|
||||
{
|
||||
Pose3 id;
|
||||
Vector v(6);
|
||||
fill(v.begin(), v.end(), 0);
|
||||
Vector v = zero(6);
|
||||
v(0) = 0.3;
|
||||
CHECK(assert_equal(expmapFull<Pose3>(id,v), Pose3(R, Point3())));
|
||||
v(3)=0.2;v(4)=0.394742;v(5)=-2.08998;
|
||||
|
@ -126,7 +123,6 @@ TEST(Pose3, Adjoint)
|
|||
|
||||
/* ************************************************************************* */
|
||||
/** Agrawal06iros version */
|
||||
using namespace boost::numeric::ublas;
|
||||
Pose3 Agrawal06iros(const Vector& xi) {
|
||||
Vector w = vector_range<const Vector>(xi, range(0,3));
|
||||
Vector v = vector_range<const Vector>(xi, range(3,6));
|
||||
|
@ -209,10 +205,9 @@ TEST(Pose3, Adjoint_full)
|
|||
|
||||
/* ************************************************************************* */
|
||||
/** Agrawal06iros version */
|
||||
using namespace boost::numeric::ublas;
|
||||
Pose3 Agrawal06iros(const Vector& xi) {
|
||||
Vector w = vector_range<const Vector>(xi, range(0,3));
|
||||
Vector v = vector_range<const Vector>(xi, range(3,6));
|
||||
Vector w = xi.head(3);
|
||||
Vector v = xi.tail(3);
|
||||
double t = norm_2(w);
|
||||
if (t < 1e-5)
|
||||
return Pose3(Rot3(), Point3::Expmap(v));
|
||||
|
|
|
@ -136,8 +136,7 @@ TEST( Rot3, rodriguez4)
|
|||
/* ************************************************************************* */
|
||||
TEST( Rot3, expmap)
|
||||
{
|
||||
Vector v(3);
|
||||
fill(v.begin(), v.end(), 0);
|
||||
Vector v = zero(3);
|
||||
CHECK(assert_equal(R.expmap(v), R));
|
||||
}
|
||||
|
||||
|
|
|
@ -77,10 +77,6 @@ LDADD = libinference.la ../base/libbase.la
|
|||
LDADD += ../../CppUnitLite/libCppUnitLite.a
|
||||
AM_DEFAULT_SOURCE_EXT = .cpp
|
||||
|
||||
if USE_ACCELERATE_MACOS
|
||||
AM_LDFLAGS += -Wl,/System/Library/Frameworks/Accelerate.framework/Accelerate
|
||||
endif
|
||||
|
||||
# rule to run an executable
|
||||
%.run: % $(LDADD)
|
||||
./$^
|
||||
|
@ -89,7 +85,3 @@ endif
|
|||
%.valgrind: % $(LDADD)
|
||||
valgrind ./$^
|
||||
|
||||
if USE_LAPACK
|
||||
AM_CXXFLAGS += -DGT_USE_LAPACK
|
||||
endif
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ boost::shared_ptr<VectorValues> allocateVectorValues(const GaussianBayesNet& bn)
|
|||
vector<size_t> dimensions(bn.size());
|
||||
Index var = 0;
|
||||
BOOST_FOREACH(const boost::shared_ptr<const GaussianConditional> conditional, bn) {
|
||||
dimensions[var++] = conditional->get_R().size1();
|
||||
dimensions[var++] = conditional->get_R().rows();
|
||||
}
|
||||
return boost::shared_ptr<VectorValues>(new VectorValues(dimensions));
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ VectorValues backSubstituteTranspose(const GaussianBayesNet& bn,
|
|||
// i^th part of L*gy=gx is done block-column by block-column of L
|
||||
BOOST_FOREACH(const boost::shared_ptr<const GaussianConditional> cg, bn) {
|
||||
Index j = cg->key();
|
||||
gy[j] = gtsam::backSubstituteUpper(gy[j],cg->get_R());
|
||||
gy[j] = gtsam::backSubstituteUpper(gy[j],Matrix(cg->get_R()));
|
||||
GaussianConditional::const_iterator it;
|
||||
for (it = cg->beginParents(); it!= cg->endParents(); it++) {
|
||||
const Index i = *it;
|
||||
|
@ -193,7 +193,7 @@ pair<Matrix,Vector> matrix(const GaussianBayesNet& bn) {
|
|||
GaussianConditional::const_iterator keyS = cg->beginParents();
|
||||
for (; keyS!=cg->endParents(); keyS++) {
|
||||
Matrix S = cg->get_S(keyS); // get S matrix
|
||||
const size_t m = S.size1(), n = S.size2(); // find S size
|
||||
const size_t m = S.rows(), n = S.cols(); // find S size
|
||||
const size_t J = mapping[*keyS]; // find column index
|
||||
for (size_t i=0;i<m;i++)
|
||||
for(size_t j=0;j<n;j++)
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <boost/numeric/ublas/vector.hpp>
|
||||
#include <boost/numeric/ublas/operation.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/lambda/bind.hpp>
|
||||
|
||||
|
@ -27,7 +25,6 @@
|
|||
#include <gtsam/base/Matrix-inl.h>
|
||||
|
||||
using namespace std;
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
|
@ -40,81 +37,82 @@ GaussianConditional::GaussianConditional(Index key) : IndexConditional(key), rsd
|
|||
/* ************************************************************************* */
|
||||
GaussianConditional::GaussianConditional(Index key,const Vector& d, const Matrix& R, const Vector& sigmas) :
|
||||
IndexConditional(key), rsd_(matrix_), sigmas_(sigmas) {
|
||||
assert(R.size1() <= R.size2());
|
||||
size_t dims[] = { R.size2(), 1 };
|
||||
assert(R.rows() <= R.cols());
|
||||
size_t dims[] = { R.cols(), 1 };
|
||||
rsd_.copyStructureFrom(rsd_type(matrix_, dims, dims+2, d.size()));
|
||||
ublas::noalias(rsd_(0)) = ublas::triangular_adaptor<const Matrix, ublas::upper>(R);
|
||||
ublas::noalias(get_d_()) = d;
|
||||
rsd_(0) = R; //.triangularView<Eigen::Upper>();
|
||||
get_d_() = d;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
GaussianConditional::GaussianConditional(Index key, const Vector& d, const Matrix& R,
|
||||
Index name1, const Matrix& S, const Vector& sigmas) :
|
||||
IndexConditional(key,name1), rsd_(matrix_), sigmas_(sigmas) {
|
||||
assert(R.size1() <= R.size2());
|
||||
size_t dims[] = { R.size2(), S.size2(), 1 };
|
||||
assert(R.rows() <= R.cols());
|
||||
size_t dims[] = { R.cols(), S.cols(), 1 };
|
||||
rsd_.copyStructureFrom(rsd_type(matrix_, dims, dims+3, d.size()));
|
||||
ublas::noalias(rsd_(0)) = ublas::triangular_adaptor<const Matrix, ublas::upper>(R);
|
||||
ublas::noalias(rsd_(1)) = S;
|
||||
ublas::noalias(get_d_()) = d;
|
||||
rsd_(0) = R.triangularView<Eigen::Upper>();
|
||||
rsd_(1) = S;
|
||||
get_d_() = d;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
GaussianConditional::GaussianConditional(Index key, const Vector& d, const Matrix& R,
|
||||
Index name1, const Matrix& S, Index name2, const Matrix& T, const Vector& sigmas) :
|
||||
IndexConditional(key,name1,name2), rsd_(matrix_), sigmas_(sigmas) {
|
||||
assert(R.size1() <= R.size2());
|
||||
size_t dims[] = { R.size2(), S.size2(), T.size2(), 1 };
|
||||
assert(R.rows() <= R.cols());
|
||||
size_t dims[] = { R.cols(), S.cols(), T.cols(), 1 };
|
||||
rsd_.copyStructureFrom(rsd_type(matrix_, dims, dims+4, d.size()));
|
||||
ublas::noalias(rsd_(0)) = ublas::triangular_adaptor<const Matrix, ublas::upper>(R);
|
||||
ublas::noalias(rsd_(1)) = S;
|
||||
ublas::noalias(rsd_(2)) = T;
|
||||
ublas::noalias(get_d_()) = d;
|
||||
rsd_(0) = R.triangularView<Eigen::Upper>();
|
||||
rsd_(1) = S;
|
||||
rsd_(2) = T;
|
||||
get_d_() = d;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
GaussianConditional::GaussianConditional(Index key, const Vector& d,
|
||||
const Matrix& R, const list<pair<Index, Matrix> >& parents, const Vector& sigmas) :
|
||||
IndexConditional(key, GetKeys(parents.size(), parents.begin(), parents.end())), rsd_(matrix_), sigmas_(sigmas) {
|
||||
assert(R.size1() <= R.size2());
|
||||
assert(R.rows() <= R.cols());
|
||||
size_t dims[1+parents.size()+1];
|
||||
dims[0] = R.size2();
|
||||
dims[0] = R.cols();
|
||||
size_t j=1;
|
||||
std::list<std::pair<Index, Matrix> >::const_iterator parent=parents.begin();
|
||||
for(; parent!=parents.end(); ++parent,++j)
|
||||
dims[j] = parent->second.size2();
|
||||
dims[j] = parent->second.cols();
|
||||
dims[j] = 1;
|
||||
rsd_.copyStructureFrom(rsd_type(matrix_, dims, dims+1+parents.size()+1, d.size()));
|
||||
ublas::noalias(rsd_(0)) = ublas::triangular_adaptor<const Matrix, ublas::upper>(R);
|
||||
rsd_(0) = R.triangularView<Eigen::Upper>();
|
||||
j = 1;
|
||||
for(std::list<std::pair<Index, Matrix> >::const_iterator parent=parents.begin(); parent!=parents.end(); ++parent) {
|
||||
ublas::noalias(rsd_(j)) = parent->second;
|
||||
rsd_(j).noalias() = parent->second;
|
||||
++ j;
|
||||
}
|
||||
ublas::noalias(get_d_()) = d;
|
||||
get_d_().noalias() = d;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void GaussianConditional::print(const string &s) const
|
||||
{
|
||||
cout << s << ": density on " << key() << endl;
|
||||
gtsam::print(get_R(),"R");
|
||||
gtsam::print(Matrix(get_R()),"R");
|
||||
for(const_iterator it = beginParents() ; it != endParents() ; it++ ) {
|
||||
gtsam::print(get_S(it), (boost::format("A[%1%]")%(*it)).str());
|
||||
gtsam::print(Matrix(get_S(it)), (boost::format("A[%1%]")%(*it)).str());
|
||||
}
|
||||
gtsam::print(get_d(),"d");
|
||||
gtsam::print(Vector(get_d()),"d");
|
||||
gtsam::print(sigmas_,"sigmas");
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool GaussianConditional::equals(const GaussianConditional &c, double tol) const {
|
||||
// check if the size of the parents_ map is the same
|
||||
if (parents().size() != c.parents().size()) return false;
|
||||
if (parents().size() != c.parents().size())
|
||||
return false;
|
||||
|
||||
// check if R_ and d_ are linear independent
|
||||
for (size_t i=0; i<rsd_.size1(); i++) {
|
||||
list<Vector> rows1; rows1.push_back(row_(get_R(), i));
|
||||
list<Vector> rows2; rows2.push_back(row_(c.get_R(), i));
|
||||
for (size_t i=0; i<rsd_.rows(); i++) {
|
||||
list<Vector> rows1; rows1.push_back(Vector(get_R().row(i)));
|
||||
list<Vector> rows2; rows2.push_back(Vector(c.get_R().row(i)));
|
||||
|
||||
// check if the matrices are the same
|
||||
// iterate over the parents_ map
|
||||
|
@ -122,13 +120,14 @@ bool GaussianConditional::equals(const GaussianConditional &c, double tol) const
|
|||
const_iterator it2 = c.beginParents() + (it-beginParents());
|
||||
if(*it != *(it2))
|
||||
return false;
|
||||
rows1.push_back(row_(get_S(it), i));
|
||||
rows2.push_back(row_(c.get_S(it2), i));
|
||||
rows1.push_back(row(get_S(it), i));
|
||||
rows2.push_back(row(c.get_S(it2), i));
|
||||
}
|
||||
|
||||
Vector row1 = concatVectors(rows1);
|
||||
Vector row2 = concatVectors(rows2);
|
||||
if (!linear_dependent(row1, row2, tol)) return false;
|
||||
if (!linear_dependent(row1, row2, tol))
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if sigmas are equal
|
||||
|
@ -148,10 +147,10 @@ Vector GaussianConditional::solve(const VectorValues& x) const {
|
|||
if(debug) print("Solving conditional ");
|
||||
Vector rhs(get_d());
|
||||
for (const_iterator parent = beginParents(); parent != endParents(); ++parent) {
|
||||
ublas::axpy_prod(-get_S(parent), x[*parent], rhs, false);
|
||||
|
||||
rhs += -get_S(parent) * x[*parent];
|
||||
// ublas::axpy_prod(-get_S(parent), x[*parent], rhs, false);
|
||||
}
|
||||
if(debug) gtsam::print(get_R(), "Calling backSubstituteUpper on ");
|
||||
if(debug) gtsam::print(Matrix(get_R()), "Calling backSubstituteUpper on ");
|
||||
if(debug) gtsam::print(rhs, "rhs: ");
|
||||
if(debug) {
|
||||
Vector soln = backSubstituteUpper(get_R(), rhs, false);
|
||||
|
@ -165,8 +164,8 @@ Vector GaussianConditional::solve(const VectorValues& x) const {
|
|||
Vector GaussianConditional::solve(const Permuted<VectorValues>& x) const {
|
||||
Vector rhs(get_d());
|
||||
for (const_iterator parent = beginParents(); parent != endParents(); ++parent) {
|
||||
ublas::axpy_prod(-get_S(parent), x[*parent], rhs, false);
|
||||
|
||||
rhs += -get_S(parent) * x[*parent];
|
||||
// ublas::axpy_prod(-get_S(parent), x[*parent], rhs, false);
|
||||
}
|
||||
return backSubstituteUpper(get_R(), rhs, false);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <vector>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/numeric/ublas/triangular.hpp>
|
||||
|
||||
#include <gtsam/base/types.h>
|
||||
#include <gtsam/inference/IndexConditional.h>
|
||||
|
@ -48,7 +47,8 @@ public:
|
|||
typedef boost::shared_ptr<GaussianConditional> shared_ptr;
|
||||
|
||||
/** Store the conditional matrix as upper-triangular column-major */
|
||||
typedef boost::numeric::ublas::triangular_matrix<double, boost::numeric::ublas::upper, boost::numeric::ublas::column_major> AbMatrix;
|
||||
// typedef boost::numeric::ublas::triangular_matrix<double, boost::numeric::ublas::upper, boost::numeric::ublas::column_major> AbMatrix;
|
||||
typedef MatrixColMajor AbMatrix;
|
||||
typedef VerticalBlockView<AbMatrix> rsd_type;
|
||||
|
||||
typedef rsd_type::Block r_type;
|
||||
|
@ -112,13 +112,15 @@ public:
|
|||
bool equals(const GaussianConditional &cg, double tol = 1e-9) const;
|
||||
|
||||
/** dimension of multivariate variable */
|
||||
size_t dim() const { return rsd_.size1(); }
|
||||
size_t dim() const { return rsd_.rows(); }
|
||||
|
||||
/** return stuff contained in GaussianConditional */
|
||||
rsd_type::constColumn get_d() const { return rsd_.column(1+nrParents(), 0); }
|
||||
const_d_type get_d() const { return rsd_.column(1+nrParents(), 0); }
|
||||
rsd_type::constBlock get_R() const { return rsd_(0); }
|
||||
rsd_type::constBlock get_S(const_iterator variable) const { return rsd_(variable - this->begin()); }
|
||||
const Vector& get_sigmas() const {return sigmas_;}
|
||||
const AbMatrix& matrix() const { return matrix_; }
|
||||
const rsd_type& rsd() const { return rsd_; } /// DEBUGGING ONLY
|
||||
|
||||
/**
|
||||
* Copy to a Factor (this creates a JacobianFactor and returns it as its
|
||||
|
|
|
@ -107,7 +107,7 @@ namespace gtsam {
|
|||
1> (), factorEntries[entry].get<2> ()));
|
||||
|
||||
// Increment row index
|
||||
i += jacobianFactor->size1();
|
||||
i += jacobianFactor->rows();
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ namespace gtsam {
|
|||
++ jointVarpos;
|
||||
}
|
||||
BOOST_FOREACH(const JacobianFactor::shared_ptr& factor, factors) {
|
||||
m += factor->size1();
|
||||
m += factor->rows();
|
||||
}
|
||||
}
|
||||
return boost::make_tuple(varDims, m, n);
|
||||
|
@ -275,7 +275,8 @@ namespace gtsam {
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
static FastMap<Index, SlotEntry> findScatterAndDims//
|
||||
//static
|
||||
FastMap<Index, SlotEntry> findScatterAndDims
|
||||
(const FactorGraph<GaussianFactor>& factors) {
|
||||
|
||||
static const bool debug = false;
|
||||
|
|
|
@ -61,6 +61,9 @@ namespace gtsam {
|
|||
return e;
|
||||
}
|
||||
|
||||
/** DEBUG ONLY: TODO: hide again later */
|
||||
FastMap<Index, SlotEntry> findScatterAndDims(const FactorGraph<GaussianFactor>& factors);
|
||||
|
||||
/**
|
||||
* A Linear Factor Graph is a factor graph where all factors are Gaussian, i.e.
|
||||
* Factor == GaussianFactor
|
||||
|
|
|
@ -24,7 +24,7 @@ using namespace gtsam;
|
|||
#include <gtsam/inference/ISAM-inl.h>
|
||||
template class ISAM<GaussianConditional>;
|
||||
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
//namespace ublas = boost::numeric::ublas;
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
|
@ -42,7 +42,7 @@ BayesNet<GaussianConditional>::shared_ptr GaussianISAM::marginalBayesNet(Index j
|
|||
std::pair<Vector, Matrix> GaussianISAM::marginal(Index j) const {
|
||||
GaussianConditional::shared_ptr conditional = marginalBayesNet(j)->front();
|
||||
Matrix R = conditional->get_R();
|
||||
return make_pair(conditional->get_d(), inverse(ublas::prod(ublas::trans(R), R)));
|
||||
return make_pair(conditional->get_d(), (R.transpose() * R).inverse());
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
@ -20,10 +20,6 @@
|
|||
|
||||
#include <gtsam/inference/GenericMultifrontalSolver-inl.h>
|
||||
|
||||
#include <boost/numeric/ublas/matrix.hpp>
|
||||
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -75,7 +71,8 @@ std::pair<Vector, Matrix> GaussianMultifrontalSolver::marginalCovariance(Index j
|
|||
fg.push_back(Base::marginalFactor(j,&EliminateQR));
|
||||
GaussianConditional::shared_ptr conditional = EliminateQR(fg,1).first->front();
|
||||
Matrix R = conditional->get_R();
|
||||
return make_pair(conditional->get_d(), inverse(ublas::prod(ublas::trans(R), R)));
|
||||
return make_pair(conditional->get_d(), (R.transpose() * R).inverse());
|
||||
// return make_pair(conditional->get_d(), inverse(ublas::prod(ublas::trans(R), R)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,10 +21,6 @@
|
|||
|
||||
#include <gtsam/inference/GenericSequentialSolver-inl.h>
|
||||
|
||||
#include <boost/numeric/ublas/matrix.hpp>
|
||||
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -91,7 +87,8 @@ std::pair<Vector, Matrix> GaussianSequentialSolver::marginalCovariance(Index j)
|
|||
fg.push_back(Base::marginalFactor(j, &EliminateQR));
|
||||
GaussianConditional::shared_ptr conditional = EliminateQR(fg, 1).first->front();
|
||||
Matrix R = conditional->get_R();
|
||||
return make_pair(conditional->get_d(), inverse(ublas::prod(ublas::trans(R),R)));
|
||||
return make_pair(conditional->get_d(), (R.transpose() * R).inverse());
|
||||
// return make_pair(conditional->get_d(), inverse(ublas::prod(ublas::trans(R),R)));
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
@ -34,390 +34,406 @@
|
|||
#include <boost/lambda/lambda.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include <boost/numeric/ublas/triangular.hpp>
|
||||
#include <boost/numeric/ublas/symmetric.hpp>
|
||||
#include <boost/numeric/ublas/io.hpp>
|
||||
#include <boost/numeric/ublas/matrix_proxy.hpp>
|
||||
#include <boost/numeric/ublas/vector_proxy.hpp>
|
||||
#include <boost/numeric/ublas/blas.hpp>
|
||||
|
||||
#include <gtsam/3rdparty/Eigen/Core>
|
||||
#include <gtsam/3rdparty/Eigen/Dense>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
using namespace boost::lambda;
|
||||
|
||||
namespace gtsam {
|
||||
|
||||
/* ************************************************************************* */
|
||||
void HessianFactor::assertInvariants() const {
|
||||
/* ************************************************************************* */
|
||||
void HessianFactor::assertInvariants() const {
|
||||
#ifndef NDEBUG
|
||||
// Check for non-finite values
|
||||
for(size_t i=0; i<matrix_.size1(); ++i)
|
||||
for(size_t j=i; j<matrix_.size2(); ++j)
|
||||
if(!isfinite(matrix_(i,j)))
|
||||
throw invalid_argument("HessianFactor contains non-finite matrix entries.");
|
||||
// Check for non-finite values
|
||||
for(size_t i=0; i<(size_t) matrix_.rows(); ++i)
|
||||
for(size_t j=i; j<(size_t) matrix_.cols(); ++j)
|
||||
if(!isfinite(matrix_(i,j)))
|
||||
throw invalid_argument("HessianFactor contains non-finite matrix entries.");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor(const HessianFactor& gf) :
|
||||
GaussianFactor(gf), info_(matrix_) {
|
||||
info_.assignNoalias(gf.info_);
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor() : info_(matrix_) {
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor(Index j1, const Matrix& G, const Vector& g, double f) :
|
||||
GaussianFactor(j1), info_(matrix_) {
|
||||
if(G.size1() != G.size2() || G.size1() != g.size())
|
||||
throw invalid_argument("Inconsistent matrix and/or vector dimensions in HessianFactor constructor");
|
||||
size_t dims[] = { G.size1(), 1 };
|
||||
InfoMatrix fullMatrix(G.size1() + 1, G.size1() + 1);
|
||||
BlockInfo infoMatrix(fullMatrix, dims, dims+2);
|
||||
infoMatrix(0,0) = G;
|
||||
infoMatrix.column(0,1,0) = g;
|
||||
infoMatrix(1,1)(0,0) = f;
|
||||
infoMatrix.swap(info_);
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor(Index j1, Index j2,
|
||||
const Matrix& G11, const Matrix& G12, const Vector& g1,
|
||||
const Matrix& G22, const Vector& g2, double f) :
|
||||
GaussianFactor(j1, j2), info_(matrix_) {
|
||||
if(G11.size1() != G11.size2() || G11.size1() != G12.size1() || G11.size1() != g1.size() ||
|
||||
G22.size2() != G12.size2() || G22.size2() != g2.size())
|
||||
throw invalid_argument("Inconsistent matrix and/or vector dimensions in HessianFactor constructor");
|
||||
size_t dims[] = { G11.size1(), G22.size1(), 1 };
|
||||
InfoMatrix fullMatrix(G11.size1() + G22.size1() + 1, G11.size1() + G22.size1() + 1);
|
||||
BlockInfo infoMatrix(fullMatrix, dims, dims+3);
|
||||
infoMatrix(0,0) = G11;
|
||||
infoMatrix(0,1) = G12;
|
||||
infoMatrix.column(0,2,0) = g1;
|
||||
infoMatrix(1,1) = G22;
|
||||
infoMatrix.column(1,2,0) = g2;
|
||||
infoMatrix(2,2)(0,0) = f;
|
||||
infoMatrix.swap(info_);
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor(const GaussianConditional& cg) : GaussianFactor(cg), info_(matrix_) {
|
||||
JacobianFactor jf(cg);
|
||||
info_.copyStructureFrom(jf.Ab_);
|
||||
ublas::noalias(ublas::symmetric_adaptor<MatrixColMajor,ublas::upper>(matrix_)) =
|
||||
ublas::prod(ublas::trans(jf.matrix_), jf.matrix_);
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor(const GaussianFactor& gf) : info_(matrix_) {
|
||||
// Copy the variable indices
|
||||
(GaussianFactor&)(*this) = gf;
|
||||
// Copy the matrix data depending on what type of factor we're copying from
|
||||
if(dynamic_cast<const JacobianFactor*>(&gf)) {
|
||||
const JacobianFactor& jf(static_cast<const JacobianFactor&>(gf));
|
||||
if(jf.model_->isConstrained())
|
||||
throw invalid_argument("Cannot construct HessianFactor from JacobianFactor with constrained noise model");
|
||||
else {
|
||||
Vector invsigmas = jf.model_->invsigmas();
|
||||
typedef Eigen::Map<const Eigen::MatrixXd> ConstEigenMap;
|
||||
typedef Eigen::Map<Eigen::MatrixXd> EigenMap;
|
||||
typedef typeof(ConstEigenMap(&jf.matrix_(0,0),0,0).block(0,0,0,0)) EigenBlock;
|
||||
EigenBlock A(ConstEigenMap(&jf.matrix_(0,0),jf.matrix_.size1(),jf.matrix_.size2()).block(
|
||||
jf.Ab_.rowStart(),jf.Ab_.offset(0), jf.Ab_.full().size1(), jf.Ab_.full().size2()));
|
||||
typedef typeof(Eigen::Map<const Eigen::VectorXd>(&invsigmas(0),0).asDiagonal()) EigenDiagonal;
|
||||
EigenDiagonal R(Eigen::Map<const Eigen::VectorXd>(&invsigmas(0),jf.model_->dim()).asDiagonal());
|
||||
info_.copyStructureFrom(jf.Ab_);
|
||||
EigenMap L(EigenMap(&matrix_(0,0), matrix_.size1(), matrix_.size2()));
|
||||
L.noalias() = A.transpose() * R * R * A;
|
||||
}
|
||||
} else if(dynamic_cast<const HessianFactor*>(&gf)) {
|
||||
const HessianFactor& hf(static_cast<const HessianFactor&>(gf));
|
||||
info_.assignNoalias(hf.info_);
|
||||
} else
|
||||
throw std::invalid_argument("In HessianFactor(const GaussianFactor& gf), gf is neither a JacobianFactor nor a HessianFactor");
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor(const FactorGraph<GaussianFactor>& factors,
|
||||
const vector<size_t>& dimensions, const Scatter& scatter) :
|
||||
info_(matrix_) {
|
||||
|
||||
const bool debug = ISDEBUG("EliminateCholesky");
|
||||
// Form Ab' * Ab
|
||||
tic(1, "allocate");
|
||||
info_.resize(dimensions.begin(), dimensions.end(), false);
|
||||
toc(1, "allocate");
|
||||
tic(2, "zero");
|
||||
ublas::noalias(matrix_) = ublas::zero_matrix<double>(matrix_.size1(),matrix_.size2());
|
||||
toc(2, "zero");
|
||||
tic(3, "update");
|
||||
BOOST_FOREACH(const GaussianFactor::shared_ptr& factor, factors)
|
||||
{
|
||||
shared_ptr hessian(boost::dynamic_pointer_cast<HessianFactor>(factor));
|
||||
if (hessian)
|
||||
updateATA(*hessian, scatter);
|
||||
else {
|
||||
JacobianFactor::shared_ptr jacobianFactor(boost::dynamic_pointer_cast<JacobianFactor>(factor));
|
||||
if (jacobianFactor)
|
||||
updateATA(*jacobianFactor, scatter);
|
||||
else
|
||||
throw invalid_argument("GaussianFactor is neither Hessian nor Jacobian");
|
||||
}
|
||||
}
|
||||
toc(3, "update");
|
||||
|
||||
if (debug) gtsam::print(matrix_, "Ab' * Ab: ");
|
||||
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void HessianFactor::print(const std::string& s) const {
|
||||
cout << s << "\n";
|
||||
cout << " keys: ";
|
||||
for(const_iterator key=this->begin(); key!=this->end(); ++key)
|
||||
cout << *key << "(" << this->getDim(key) << ") ";
|
||||
cout << "\n";
|
||||
gtsam::print(ublas::symmetric_adaptor<const constBlock,ublas::upper>(
|
||||
info_.range(0,info_.nBlocks(), 0,info_.nBlocks())), "Ab^T * Ab: ");
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool HessianFactor::equals(const GaussianFactor& lf, double tol) const {
|
||||
if(!dynamic_cast<const HessianFactor*>(&lf))
|
||||
return false;
|
||||
else {
|
||||
MatrixColMajor thisMatrix = ublas::symmetric_adaptor<const MatrixColMajor,ublas::upper>(this->info_.full());
|
||||
thisMatrix(thisMatrix.size1()-1, thisMatrix.size2()-1) = 0.0;
|
||||
MatrixColMajor rhsMatrix = ublas::symmetric_adaptor<const MatrixColMajor,ublas::upper>(static_cast<const HessianFactor&>(lf).info_.full());
|
||||
rhsMatrix(rhsMatrix.size1()-1, rhsMatrix.size2()-1) = 0.0;
|
||||
return equal_with_abs_tol(thisMatrix, rhsMatrix, tol);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double HessianFactor::error(const VectorValues& c) const {
|
||||
return 0.5 * (ublas::inner_prod(c.vector(),
|
||||
ublas::prod(
|
||||
ublas::symmetric_adaptor<const constBlock,ublas::upper>(info_.range(0, this->size(), 0, this->size())),
|
||||
c.vector())) -
|
||||
2.0*ublas::inner_prod(c.vector(), info_.rangeColumn(0, this->size(), this->size(), 0)) +
|
||||
info_(this->size(), this->size())(0,0));
|
||||
}
|
||||
|
||||
void HessianFactor::updateATA(const HessianFactor& update, const Scatter& scatter) {
|
||||
|
||||
// This function updates 'combined' with the information in 'update'.
|
||||
// 'scatter' maps variables in the update factor to slots in the combined
|
||||
// factor.
|
||||
|
||||
const bool debug = ISDEBUG("updateATA");
|
||||
|
||||
// First build an array of slots
|
||||
tic(1, "slots");
|
||||
size_t slots[update.size()];
|
||||
size_t slot = 0;
|
||||
BOOST_FOREACH(Index j, update) {
|
||||
slots[slot] = scatter.find(j)->second.slot;
|
||||
++ slot;
|
||||
}
|
||||
toc(1, "slots");
|
||||
|
||||
if(debug) {
|
||||
this->print("Updating this: ");
|
||||
update.print("with: ");
|
||||
}
|
||||
|
||||
Eigen::Map<Eigen::MatrixXd> information(&matrix_(0,0), matrix_.size1(), matrix_.size2());
|
||||
Eigen::Map<const Eigen::MatrixXd> updateInform(&update.matrix_(0,0), update.matrix_.size1(), update.matrix_.size2());
|
||||
|
||||
// Apply updates to the upper triangle
|
||||
tic(3, "update");
|
||||
assert(this->info_.nBlocks() - 1 == scatter.size());
|
||||
for(size_t j2=0; j2<update.info_.nBlocks(); ++j2) {
|
||||
size_t slot2 = (j2 == update.size()) ? this->info_.nBlocks()-1 : slots[j2];
|
||||
for(size_t j1=0; j1<=j2; ++j1) {
|
||||
size_t slot1 = (j1 == update.size()) ? this->info_.nBlocks()-1 : slots[j1];
|
||||
if(slot2 > slot1) {
|
||||
if(debug)
|
||||
cout << "Updating (" << slot1 << "," << slot2 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
information.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).size1(), info_(slot1,slot2).size2()).noalias() +=
|
||||
updateInform.block(update.info_.offset(j1), update.info_.offset(j2), update.info_(j1,j2).size1(), update.info_(j1,j2).size2());
|
||||
} else if(slot1 > slot2) {
|
||||
if(debug)
|
||||
cout << "Updating (" << slot2 << "," << slot1 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
information.block(info_.offset(slot2), info_.offset(slot1), info_(slot2,slot1).size1(), info_(slot2,slot1).size2()).noalias() +=
|
||||
updateInform.block(update.info_.offset(j1), update.info_.offset(j2), update.info_(j1,j2).size1(), update.info_(j1,j2).size2()).transpose();
|
||||
} else {
|
||||
if(debug)
|
||||
cout << "Updating (" << slot1 << "," << slot2 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
information.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).size1(), info_(slot1,slot2).size2()).triangularView<Eigen::Upper>() +=
|
||||
updateInform.block(update.info_.offset(j1), update.info_.offset(j2), update.info_(j1,j2).size1(), update.info_(j1,j2).size2());
|
||||
}
|
||||
if(debug) cout << "Updating block " << slot1 << "," << slot2 << " from block " << j1 << "," << j2 << "\n";
|
||||
if(debug) this->print();
|
||||
}
|
||||
}
|
||||
toc(3, "update");
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor(const HessianFactor& gf) :
|
||||
GaussianFactor(gf), info_(matrix_) {
|
||||
info_.assignNoalias(gf.info_);
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor() : info_(matrix_) {
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor(Index j1, const Matrix& G, const Vector& g, double f) :
|
||||
GaussianFactor(j1), info_(matrix_) {
|
||||
if(G.rows() != G.cols() || G.rows() != g.size())
|
||||
throw invalid_argument("Inconsistent matrix and/or vector dimensions in HessianFactor constructor");
|
||||
size_t dims[] = { G.rows(), 1 };
|
||||
InfoMatrix fullMatrix(G.rows() + 1, G.rows() + 1);
|
||||
BlockInfo infoMatrix(fullMatrix, dims, dims+2);
|
||||
infoMatrix(0,0) = G;
|
||||
infoMatrix.column(0,1,0) = g;
|
||||
infoMatrix(1,1)(0,0) = f;
|
||||
infoMatrix.swap(info_);
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor(Index j1, Index j2,
|
||||
const Matrix& G11, const Matrix& G12, const Vector& g1,
|
||||
const Matrix& G22, const Vector& g2, double f) :
|
||||
GaussianFactor(j1, j2), info_(matrix_) {
|
||||
if(G11.rows() != G11.cols() || G11.rows() != G12.rows() || G11.rows() != g1.size() ||
|
||||
G22.cols() != G12.cols() || G22.cols() != g2.size())
|
||||
throw invalid_argument("Inconsistent matrix and/or vector dimensions in HessianFactor constructor");
|
||||
size_t dims[] = { G11.rows(), G22.rows(), 1 };
|
||||
InfoMatrix fullMatrix(G11.rows() + G22.rows() + 1, G11.rows() + G22.rows() + 1);
|
||||
BlockInfo infoMatrix(fullMatrix, dims, dims+3);
|
||||
infoMatrix(0,0) = G11;
|
||||
infoMatrix(0,1) = G12;
|
||||
infoMatrix.column(0,2,0) = g1;
|
||||
infoMatrix(1,1) = G22;
|
||||
infoMatrix.column(1,2,0) = g2;
|
||||
infoMatrix(2,2)(0,0) = f;
|
||||
infoMatrix.swap(info_);
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor(const GaussianConditional& cg) : GaussianFactor(cg), info_(matrix_) {
|
||||
JacobianFactor jf(cg);
|
||||
info_.copyStructureFrom(jf.Ab_);
|
||||
// ublas::noalias(ublas::symmetric_adaptor<MatrixColMajor,ublas::upper>(matrix_)) =
|
||||
// ublas::prod(ublas::trans(jf.matrix_), jf.matrix_);
|
||||
matrix_.noalias() = jf.matrix_.transpose() * jf.matrix_;
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor(const GaussianFactor& gf) : info_(matrix_) {
|
||||
// Copy the variable indices
|
||||
(GaussianFactor&)(*this) = gf;
|
||||
// Copy the matrix data depending on what type of factor we're copying from
|
||||
if(dynamic_cast<const JacobianFactor*>(&gf)) {
|
||||
const JacobianFactor& jf(static_cast<const JacobianFactor&>(gf));
|
||||
if(jf.model_->isConstrained())
|
||||
throw invalid_argument("Cannot construct HessianFactor from JacobianFactor with constrained noise model");
|
||||
else {
|
||||
Vector invsigmas = jf.model_->invsigmas().cwiseProduct(jf.model_->invsigmas());
|
||||
info_.copyStructureFrom(jf.Ab_);
|
||||
BlockInfo::constBlock A = jf.Ab_.full();
|
||||
matrix_.noalias() = A.transpose() * invsigmas.asDiagonal() * A;
|
||||
|
||||
// typedef Eigen::Map<Eigen::MatrixXd> EigenMap;
|
||||
// typedef typeof(EigenMap(&jf.matrix_(0,0),0,0).block(0,0,0,0)) EigenBlock;
|
||||
// EigenBlock A(EigenMap(&jf.matrix_(0,0),jf.matrix_.rows(),jf.matrix_.cols()).block(jf.Ab_.rowStart(),jf.Ab_.offset(0), jf.Ab_.full().rows(), jf.Ab_.full().cols()));
|
||||
// typedef typeof(Eigen::Map<Eigen::VectorXd>(&invsigmas(0),0).asDiagonal()) EigenDiagonal;
|
||||
// EigenDiagonal R(Eigen::Map<Eigen::VectorXd>(&invsigmas(0),jf.model_->dim()).asDiagonal());
|
||||
// info_.copyStructureFrom(jf.Ab_);
|
||||
// EigenMap L(EigenMap(&matrix_(0,0), matrix_.rows(), matrix_.cols()));
|
||||
// L.noalias() = A.transpose() * R * R * A;
|
||||
}
|
||||
} else if(dynamic_cast<const HessianFactor*>(&gf)) {
|
||||
const HessianFactor& hf(static_cast<const HessianFactor&>(gf));
|
||||
info_.assignNoalias(hf.info_);
|
||||
} else
|
||||
throw std::invalid_argument("In HessianFactor(const GaussianFactor& gf), gf is neither a JacobianFactor nor a HessianFactor");
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::HessianFactor(const FactorGraph<GaussianFactor>& factors,
|
||||
const vector<size_t>& dimensions, const Scatter& scatter) :
|
||||
info_(matrix_) {
|
||||
|
||||
const bool debug = ISDEBUG("EliminateCholesky");
|
||||
// Form Ab' * Ab
|
||||
tic(1, "allocate");
|
||||
info_.resize(dimensions.begin(), dimensions.end(), false);
|
||||
toc(1, "allocate");
|
||||
tic(2, "zero");
|
||||
matrix_.noalias() = Matrix::Zero(matrix_.rows(),matrix_.cols());
|
||||
toc(2, "zero");
|
||||
tic(3, "update");
|
||||
BOOST_FOREACH(const GaussianFactor::shared_ptr& factor, factors)
|
||||
{
|
||||
shared_ptr hessian(boost::dynamic_pointer_cast<HessianFactor>(factor));
|
||||
if (hessian)
|
||||
updateATA(*hessian, scatter);
|
||||
else {
|
||||
JacobianFactor::shared_ptr jacobianFactor(boost::dynamic_pointer_cast<JacobianFactor>(factor));
|
||||
if (jacobianFactor)
|
||||
updateATA(*jacobianFactor, scatter);
|
||||
else
|
||||
throw invalid_argument("GaussianFactor is neither Hessian nor Jacobian");
|
||||
}
|
||||
}
|
||||
toc(3, "update");
|
||||
|
||||
if (debug) gtsam::print(matrix_, "Ab' * Ab: ");
|
||||
|
||||
assertInvariants();
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void HessianFactor::print(const std::string& s) const {
|
||||
cout << s << "\n";
|
||||
cout << " keys: ";
|
||||
for(const_iterator key=this->begin(); key!=this->end(); ++key)
|
||||
cout << *key << "(" << this->getDim(key) << ") ";
|
||||
cout << "\n";
|
||||
// gtsam::print(ublas::symmetric_adaptor<const constBlock,ublas::upper>(
|
||||
// info_.range(0,info_.nBlocks(), 0,info_.nBlocks())), "Ab^T * Ab: ");
|
||||
gtsam::print(MatrixColMajor(info_.range(0,info_.nBlocks(), 0,info_.nBlocks()).selfadjointView<Eigen::Upper>()), "Ab^T * Ab: ");
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
bool HessianFactor::equals(const GaussianFactor& lf, double tol) const {
|
||||
if(!dynamic_cast<const HessianFactor*>(&lf))
|
||||
return false;
|
||||
else {
|
||||
MatrixColMajor thisMatrix = this->info_.full().selfadjointView<Eigen::Upper>();
|
||||
// MatrixColMajor thisMatrix = ublas::symmetric_adaptor<const MatrixColMajor,ublas::upper>(this->info_.full());
|
||||
thisMatrix(thisMatrix.rows()-1, thisMatrix.cols()-1) = 0.0;
|
||||
MatrixColMajor rhsMatrix = static_cast<const HessianFactor&>(lf).info_.full().selfadjointView<Eigen::Upper>();
|
||||
// MatrixColMajor rhsMatrix = ublas::symmetric_adaptor<const MatrixColMajor,ublas::upper>(static_cast<const HessianFactor&>(lf).info_.full());
|
||||
rhsMatrix(rhsMatrix.rows()-1, rhsMatrix.cols()-1) = 0.0;
|
||||
return equal_with_abs_tol(thisMatrix, rhsMatrix, tol);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double HessianFactor::constant_term() const {
|
||||
return info_(this->size(), this->size())(0,0);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
HessianFactor::constColumn HessianFactor::linear_term() const {
|
||||
return info_.rangeColumn(0, this->size(), this->size(), 0);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
double HessianFactor::error(const VectorValues& c) const {
|
||||
// error 0.5*(f - 2*x'*g + x'*G*x)
|
||||
|
||||
// return 0.5 * (ublas::inner_prod(c.vector(),
|
||||
// ublas::prod(
|
||||
// ublas::symmetric_adaptor<const constBlock,ublas::upper>(info_.range(0, this->size(), 0, this->size())),
|
||||
// c.vector())) -
|
||||
// 2.0*ublas::inner_prod(c.vector(), info_.rangeColumn(0, this->size(), this->size(), 0)) +
|
||||
// info_(this->size(), this->size())(0,0));
|
||||
|
||||
// double expected_manual = 0.5 * (f - 2.0 * dxv.dot(g) + dxv.transpose() * G.selfadjointView<Eigen::Upper>() * dxv);
|
||||
const double f = constant_term();
|
||||
const double xtg = c.vector().dot(linear_term());
|
||||
const double xGx = c.vector().transpose() * info_.range(0, this->size(), 0, this->size()).selfadjointView<Eigen::Upper>() * c.vector();
|
||||
|
||||
return 0.5 * (f - 2.0 * xtg + xGx);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void HessianFactor::updateATA(const HessianFactor& update, const Scatter& scatter) {
|
||||
|
||||
// This function updates 'combined' with the information in 'update'.
|
||||
// 'scatter' maps variables in the update factor to slots in the combined
|
||||
// factor.
|
||||
|
||||
const bool debug = ISDEBUG("updateATA");
|
||||
|
||||
// First build an array of slots
|
||||
tic(1, "slots");
|
||||
size_t slots[update.size()];
|
||||
size_t slot = 0;
|
||||
BOOST_FOREACH(Index j, update) {
|
||||
slots[slot] = scatter.find(j)->second.slot;
|
||||
++ slot;
|
||||
}
|
||||
toc(1, "slots");
|
||||
|
||||
if(debug) {
|
||||
this->print("Updating this: ");
|
||||
update.print("with: ");
|
||||
}
|
||||
|
||||
// Eigen::Map<Eigen::MatrixXd> information(&matrix_(0,0), matrix_.rows(), matrix_.cols());
|
||||
// Eigen::Map<Eigen::MatrixXd> updateInform(&update.matrix_(0,0), update.matrix_.rows(), update.matrix_.cols());
|
||||
|
||||
// Apply updates to the upper triangle
|
||||
tic(3, "update");
|
||||
assert(this->info_.nBlocks() - 1 == scatter.size());
|
||||
for(size_t j2=0; j2<update.info_.nBlocks(); ++j2) {
|
||||
size_t slot2 = (j2 == update.size()) ? this->info_.nBlocks()-1 : slots[j2];
|
||||
for(size_t j1=0; j1<=j2; ++j1) {
|
||||
size_t slot1 = (j1 == update.size()) ? this->info_.nBlocks()-1 : slots[j1];
|
||||
if(slot2 > slot1) {
|
||||
if(debug)
|
||||
cout << "Updating (" << slot1 << "," << slot2 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
matrix_.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).rows(), info_(slot1,slot2).cols()).noalias() +=
|
||||
update.matrix_.block(update.info_.offset(j1), update.info_.offset(j2), update.info_(j1,j2).rows(), update.info_(j1,j2).cols());
|
||||
} else if(slot1 > slot2) {
|
||||
if(debug)
|
||||
cout << "Updating (" << slot2 << "," << slot1 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
matrix_.block(info_.offset(slot2), info_.offset(slot1), info_(slot2,slot1).rows(), info_(slot2,slot1).cols()).noalias() +=
|
||||
update.matrix_.block(update.info_.offset(j1), update.info_.offset(j2), update.info_(j1,j2).rows(), update.info_(j1,j2).cols()).transpose();
|
||||
} else {
|
||||
if(debug)
|
||||
cout << "Updating (" << slot1 << "," << slot2 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
matrix_.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).rows(), info_(slot1,slot2).cols()).triangularView<Eigen::Upper>() +=
|
||||
update.matrix_.block(update.info_.offset(j1), update.info_.offset(j2), update.info_(j1,j2).rows(), update.info_(j1,j2).cols());
|
||||
}
|
||||
if(debug) cout << "Updating block " << slot1 << "," << slot2 << " from block " << j1 << "," << j2 << "\n";
|
||||
if(debug) this->print();
|
||||
}
|
||||
}
|
||||
toc(3, "update");
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
void HessianFactor::updateATA(const JacobianFactor& update, const Scatter& scatter) {
|
||||
|
||||
// This function updates 'combined' with the information in 'update'.
|
||||
// 'scatter' maps variables in the update factor to slots in the combined
|
||||
// factor.
|
||||
// This function updates 'combined' with the information in 'update'.
|
||||
// 'scatter' maps variables in the update factor to slots in the combined
|
||||
// factor.
|
||||
|
||||
const bool debug = ISDEBUG("updateATA");
|
||||
const bool debug = ISDEBUG("updateATA");
|
||||
|
||||
// First build an array of slots
|
||||
tic(1, "slots");
|
||||
size_t slots[update.size()];
|
||||
size_t slot = 0;
|
||||
BOOST_FOREACH(Index j, update) {
|
||||
slots[slot] = scatter.find(j)->second.slot;
|
||||
++ slot;
|
||||
}
|
||||
toc(1, "slots");
|
||||
// First build an array of slots
|
||||
tic(1, "slots");
|
||||
size_t slots[update.size()];
|
||||
size_t slot = 0;
|
||||
BOOST_FOREACH(Index j, update) {
|
||||
slots[slot] = scatter.find(j)->second.slot;
|
||||
++ slot;
|
||||
}
|
||||
toc(1, "slots");
|
||||
|
||||
tic(2, "form A^T*A");
|
||||
if(update.model_->isConstrained())
|
||||
throw invalid_argument("Cannot update HessianFactor from JacobianFactor with constrained noise model");
|
||||
tic(2, "form A^T*A");
|
||||
if(update.model_->isConstrained())
|
||||
throw invalid_argument("Cannot update HessianFactor from JacobianFactor with constrained noise model");
|
||||
|
||||
if(debug) {
|
||||
this->print("Updating this: ");
|
||||
update.print("with: ");
|
||||
}
|
||||
if(debug) {
|
||||
this->print("Updating this: ");
|
||||
update.print("with: ");
|
||||
}
|
||||
|
||||
Eigen::Map<Eigen::MatrixXd> information(&matrix_(0,0), matrix_.size1(), matrix_.size2());
|
||||
Eigen::Map<const Eigen::MatrixXd> updateAf(&update.matrix_(0,0), update.matrix_.size1(), update.matrix_.size2());
|
||||
Eigen::Block<typeof(updateAf)> updateA(updateAf.block(
|
||||
update.Ab_.rowStart(),update.Ab_.offset(0), update.Ab_.full().size1(), update.Ab_.full().size2()));
|
||||
// Eigen::Map<Eigen::MatrixXd> information(&matrix_(0,0), matrix_.rows(), matrix_.cols());
|
||||
// Eigen::Map<Eigen::MatrixXd> updateAf(&update.matrix_(0,0), update.matrix_.rows(), update.matrix_.cols());
|
||||
Eigen::Block<typeof(update.matrix_)> updateA(update.matrix_.block(
|
||||
update.Ab_.rowStart(),update.Ab_.offset(0), update.Ab_.full().rows(), update.Ab_.full().cols()));
|
||||
|
||||
Eigen::MatrixXd updateInform;
|
||||
if(boost::dynamic_pointer_cast<noiseModel::Unit>(update.model_)) {
|
||||
updateInform.noalias() = updateA.transpose() * updateA;
|
||||
} else {
|
||||
noiseModel::Diagonal::shared_ptr diagonal(boost::dynamic_pointer_cast<noiseModel::Diagonal>(update.model_));
|
||||
if(diagonal) {
|
||||
typeof(Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),0).asDiagonal()) R(
|
||||
Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),update.model_->dim()).asDiagonal());
|
||||
updateInform.noalias() = updateA.transpose() * R * R * updateA;
|
||||
} else
|
||||
throw invalid_argument("In HessianFactor::updateATA, JacobianFactor noise model is neither Unit nor Diagonal");
|
||||
}
|
||||
toc(2, "form A^T*A");
|
||||
Eigen::MatrixXd updateInform;
|
||||
if(boost::dynamic_pointer_cast<noiseModel::Unit>(update.model_)) {
|
||||
updateInform.noalias() = updateA.transpose() * updateA;
|
||||
} else {
|
||||
noiseModel::Diagonal::shared_ptr diagonal(boost::dynamic_pointer_cast<noiseModel::Diagonal>(update.model_));
|
||||
if(diagonal) {
|
||||
typeof(Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),0).asDiagonal()) R(
|
||||
Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),update.model_->dim()).asDiagonal());
|
||||
updateInform.noalias() = updateA.transpose() * R * R * updateA;
|
||||
} else
|
||||
throw invalid_argument("In HessianFactor::updateATA, JacobianFactor noise model is neither Unit nor Diagonal");
|
||||
}
|
||||
toc(2, "form A^T*A");
|
||||
|
||||
// Apply updates to the upper triangle
|
||||
tic(3, "update");
|
||||
assert(this->info_.nBlocks() - 1 == scatter.size());
|
||||
for(size_t j2=0; j2<update.Ab_.nBlocks(); ++j2) {
|
||||
size_t slot2 = (j2 == update.size()) ? this->info_.nBlocks()-1 : slots[j2];
|
||||
for(size_t j1=0; j1<=j2; ++j1) {
|
||||
size_t slot1 = (j1 == update.size()) ? this->info_.nBlocks()-1 : slots[j1];
|
||||
size_t off0 = update.Ab_.offset(0);
|
||||
if(slot2 > slot1) {
|
||||
if(debug)
|
||||
cout << "Updating (" << slot1 << "," << slot2 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
information.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).size1(), info_(slot1,slot2).size2()).noalias() +=
|
||||
updateInform.block(update.Ab_.offset(j1)-off0, update.Ab_.offset(j2)-off0, update.Ab_(j1).size2(), update.Ab_(j2).size2());
|
||||
} else if(slot1 > slot2) {
|
||||
if(debug)
|
||||
cout << "Updating (" << slot2 << "," << slot1 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
information.block(info_.offset(slot2), info_.offset(slot1), info_(slot2,slot1).size1(), info_(slot2,slot1).size2()).noalias() +=
|
||||
updateInform.block(update.Ab_.offset(j1)-off0, update.Ab_.offset(j2)-off0, update.Ab_(j1).size2(), update.Ab_(j2).size2()).transpose();
|
||||
} else {
|
||||
if(debug)
|
||||
cout << "Updating (" << slot1 << "," << slot2 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
information.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).size1(), info_(slot1,slot2).size2()).triangularView<Eigen::Upper>() +=
|
||||
updateInform.block(update.Ab_.offset(j1)-off0, update.Ab_.offset(j2)-off0, update.Ab_(j1).size2(), update.Ab_(j2).size2());
|
||||
}
|
||||
if(debug) cout << "Updating block " << slot1 << "," << slot2 << " from block " << j1 << "," << j2 << "\n";
|
||||
if(debug) this->print();
|
||||
}
|
||||
}
|
||||
toc(3, "update");
|
||||
// Apply updates to the upper triangle
|
||||
tic(3, "update");
|
||||
assert(this->info_.nBlocks() - 1 == scatter.size());
|
||||
for(size_t j2=0; j2<update.Ab_.nBlocks(); ++j2) {
|
||||
size_t slot2 = (j2 == update.size()) ? this->info_.nBlocks()-1 : slots[j2];
|
||||
for(size_t j1=0; j1<=j2; ++j1) {
|
||||
size_t slot1 = (j1 == update.size()) ? this->info_.nBlocks()-1 : slots[j1];
|
||||
size_t off0 = update.Ab_.offset(0);
|
||||
if(slot2 > slot1) {
|
||||
if(debug)
|
||||
cout << "Updating (" << slot1 << "," << slot2 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
matrix_.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).rows(), info_(slot1,slot2).cols()).noalias() +=
|
||||
updateInform.block(update.Ab_.offset(j1)-off0, update.Ab_.offset(j2)-off0, update.Ab_(j1).cols(), update.Ab_(j2).cols());
|
||||
} else if(slot1 > slot2) {
|
||||
if(debug)
|
||||
cout << "Updating (" << slot2 << "," << slot1 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
matrix_.block(info_.offset(slot2), info_.offset(slot1), info_(slot2,slot1).rows(), info_(slot2,slot1).cols()).noalias() +=
|
||||
updateInform.block(update.Ab_.offset(j1)-off0, update.Ab_.offset(j2)-off0, update.Ab_(j1).cols(), update.Ab_(j2).cols()).transpose();
|
||||
} else {
|
||||
if(debug)
|
||||
cout << "Updating (" << slot1 << "," << slot2 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
matrix_.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).rows(), info_(slot1,slot2).cols()).triangularView<Eigen::Upper>() +=
|
||||
updateInform.block(update.Ab_.offset(j1)-off0, update.Ab_.offset(j2)-off0, update.Ab_(j1).cols(), update.Ab_(j2).cols());
|
||||
}
|
||||
if(debug) cout << "Updating block " << slot1 << "," << slot2 << " from block " << j1 << "," << j2 << "\n";
|
||||
if(debug) this->print();
|
||||
}
|
||||
}
|
||||
toc(3, "update");
|
||||
|
||||
// Eigen::Map<Eigen::MatrixXd> information(&matrix_(0,0), matrix_.size1(), matrix_.size2());
|
||||
// Eigen::Map<Eigen::MatrixXd> updateA(&update.matrix_(0,0), update.matrix_.size1(), update.matrix_.size2());
|
||||
//
|
||||
// // Apply updates to the upper triangle
|
||||
// tic(2, "update");
|
||||
// assert(this->info_.nBlocks() - 1 == scatter.size());
|
||||
// for(size_t j2=0; j2<update.Ab_.nBlocks(); ++j2) {
|
||||
// size_t slot2 = (j2 == update.size()) ? this->info_.nBlocks()-1 : slots[j2];
|
||||
// for(size_t j1=0; j1<=j2; ++j1) {
|
||||
// size_t slot1 = (j1 == update.size()) ? this->info_.nBlocks()-1 : slots[j1];
|
||||
// typedef typeof(updateA.block(0,0,0,0)) ABlock;
|
||||
// ABlock A1(updateA.block(update.Ab_.rowStart(),update.Ab_.offset(j1), update.Ab_(j1).size1(),update.Ab_(j1).size2()));
|
||||
// ABlock A2(updateA.block(update.Ab_.rowStart(),update.Ab_.offset(j2), update.Ab_(j2).size1(),update.Ab_(j2).size2()));
|
||||
// if(slot2 > slot1) {
|
||||
// if(debug)
|
||||
// cout << "Updating (" << slot1 << "," << slot2 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
// if(boost::dynamic_pointer_cast<noiseModel::Unit>(update.model_)) {
|
||||
// information.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).size1(), info_(slot1,slot2).size2()) +=
|
||||
// A1.transpose() * A2;
|
||||
// } else {
|
||||
// noiseModel::Diagonal::shared_ptr diagonal(boost::dynamic_pointer_cast<noiseModel::Diagonal>(update.model_));
|
||||
// if(diagonal) {
|
||||
// typeof(Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),0).asDiagonal()) R(
|
||||
// Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),update.model_->dim()).asDiagonal());
|
||||
// information.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).size1(), info_(slot1,slot2).size2()).noalias() +=
|
||||
// A1.transpose() * R * R * A2;
|
||||
// } else
|
||||
// throw invalid_argument("In HessianFactor::updateATA, JacobianFactor noise model is neither Unit nor Diagonal");
|
||||
// }
|
||||
// } else if(slot1 > slot2) {
|
||||
// if(debug)
|
||||
// cout << "Updating (" << slot2 << "," << slot1 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
// if(boost::dynamic_pointer_cast<noiseModel::Unit>(update.model_)) {
|
||||
// information.block(info_.offset(slot2), info_.offset(slot1), info_(slot2,slot1).size1(), info_(slot2,slot1).size2()).noalias() +=
|
||||
// A2.transpose() * A1;
|
||||
// } else {
|
||||
// noiseModel::Diagonal::shared_ptr diagonal(boost::dynamic_pointer_cast<noiseModel::Diagonal>(update.model_));
|
||||
// if(diagonal) {
|
||||
// typeof(Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),0).asDiagonal()) R(
|
||||
// Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),update.model_->dim()).asDiagonal());
|
||||
// information.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).size1(), info_(slot1,slot2).size2()).noalias() +=
|
||||
// A2.transpose() * R * R * A1;
|
||||
// } else
|
||||
// throw invalid_argument("In HessianFactor::updateATA, JacobianFactor noise model is neither Unit nor Diagonal");
|
||||
// }
|
||||
// } else {
|
||||
// if(debug)
|
||||
// cout << "Updating (" << slot1 << "," << slot2 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
// if(boost::dynamic_pointer_cast<noiseModel::Unit>(update.model_)) {
|
||||
// information.block(info_.offset(slot2), info_.offset(slot1), info_(slot2,slot1).size1(), info_(slot2,slot1).size2()).triangularView<Eigen::Upper>() +=
|
||||
// A1.transpose() * A1;
|
||||
// } else {
|
||||
// noiseModel::Diagonal::shared_ptr diagonal(boost::dynamic_pointer_cast<noiseModel::Diagonal>(update.model_));
|
||||
// if(diagonal) {
|
||||
// typeof(Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),0).asDiagonal()) R(
|
||||
// Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),update.model_->dim()).asDiagonal());
|
||||
// information.block(info_.offset(slot2), info_.offset(slot1), info_(slot2,slot1).size1(), info_(slot2,slot1).size2()).triangularView<Eigen::Upper>() +=
|
||||
// A1.transpose() * R * R * A1;
|
||||
// } else
|
||||
// throw invalid_argument("In HessianFactor::updateATA, JacobianFactor noise model is neither Unit nor Diagonal");
|
||||
// }
|
||||
// }
|
||||
// if(debug) cout << "Updating block " << slot1 << "," << slot2 << " from block " << j1 << "," << j2 << "\n";
|
||||
// if(debug) this->print();
|
||||
// }
|
||||
// }
|
||||
// toc(2, "update");
|
||||
// Eigen::Map<Eigen::MatrixXd> information(&matrix_(0,0), matrix_.rows(), matrix_.cols());
|
||||
// Eigen::Map<Eigen::MatrixXd> updateA(&update.matrix_(0,0), update.matrix_.rows(), update.matrix_.cols());
|
||||
//
|
||||
// // Apply updates to the upper triangle
|
||||
// tic(2, "update");
|
||||
// assert(this->info_.nBlocks() - 1 == scatter.size());
|
||||
// for(size_t j2=0; j2<update.Ab_.nBlocks(); ++j2) {
|
||||
// size_t slot2 = (j2 == update.size()) ? this->info_.nBlocks()-1 : slots[j2];
|
||||
// for(size_t j1=0; j1<=j2; ++j1) {
|
||||
// size_t slot1 = (j1 == update.size()) ? this->info_.nBlocks()-1 : slots[j1];
|
||||
// typedef typeof(updateA.block(0,0,0,0)) ABlock;
|
||||
// ABlock A1(updateA.block(update.Ab_.rowStart(),update.Ab_.offset(j1), update.Ab_(j1).rows(),update.Ab_(j1).cols()));
|
||||
// ABlock A2(updateA.block(update.Ab_.rowStart(),update.Ab_.offset(j2), update.Ab_(j2).rows(),update.Ab_(j2).cols()));
|
||||
// if(slot2 > slot1) {
|
||||
// if(debug)
|
||||
// cout << "Updating (" << slot1 << "," << slot2 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
// if(boost::dynamic_pointer_cast<noiseModel::Unit>(update.model_)) {
|
||||
// information.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).rows(), info_(slot1,slot2).cols()) +=
|
||||
// A1.transpose() * A2;
|
||||
// } else {
|
||||
// noiseModel::Diagonal::shared_ptr diagonal(boost::dynamic_pointer_cast<noiseModel::Diagonal>(update.model_));
|
||||
// if(diagonal) {
|
||||
// typeof(Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),0).asDiagonal()) R(
|
||||
// Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),update.model_->dim()).asDiagonal());
|
||||
// information.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).rows(), info_(slot1,slot2).cols()).noalias() +=
|
||||
// A1.transpose() * R * R * A2;
|
||||
// } else
|
||||
// throw invalid_argument("In HessianFactor::updateATA, JacobianFactor noise model is neither Unit nor Diagonal");
|
||||
// }
|
||||
// } else if(slot1 > slot2) {
|
||||
// if(debug)
|
||||
// cout << "Updating (" << slot2 << "," << slot1 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
// if(boost::dynamic_pointer_cast<noiseModel::Unit>(update.model_)) {
|
||||
// information.block(info_.offset(slot2), info_.offset(slot1), info_(slot2,slot1).rows(), info_(slot2,slot1).cols()).noalias() +=
|
||||
// A2.transpose() * A1;
|
||||
// } else {
|
||||
// noiseModel::Diagonal::shared_ptr diagonal(boost::dynamic_pointer_cast<noiseModel::Diagonal>(update.model_));
|
||||
// if(diagonal) {
|
||||
// typeof(Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),0).asDiagonal()) R(
|
||||
// Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),update.model_->dim()).asDiagonal());
|
||||
// information.block(info_.offset(slot1), info_.offset(slot2), info_(slot1,slot2).rows(), info_(slot1,slot2).cols()).noalias() +=
|
||||
// A2.transpose() * R * R * A1;
|
||||
// } else
|
||||
// throw invalid_argument("In HessianFactor::updateATA, JacobianFactor noise model is neither Unit nor Diagonal");
|
||||
// }
|
||||
// } else {
|
||||
// if(debug)
|
||||
// cout << "Updating (" << slot1 << "," << slot2 << ") from (" << j1 << "," << j2 << ")" << endl;
|
||||
// if(boost::dynamic_pointer_cast<noiseModel::Unit>(update.model_)) {
|
||||
// information.block(info_.offset(slot2), info_.offset(slot1), info_(slot2,slot1).rows(), info_(slot2,slot1).cols()).triangularView<Eigen::Upper>() +=
|
||||
// A1.transpose() * A1;
|
||||
// } else {
|
||||
// noiseModel::Diagonal::shared_ptr diagonal(boost::dynamic_pointer_cast<noiseModel::Diagonal>(update.model_));
|
||||
// if(diagonal) {
|
||||
// typeof(Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),0).asDiagonal()) R(
|
||||
// Eigen::Map<Eigen::VectorXd>(&update.model_->invsigmas()(0),update.model_->dim()).asDiagonal());
|
||||
// information.block(info_.offset(slot2), info_.offset(slot1), info_(slot2,slot1).rows(), info_(slot2,slot1).cols()).triangularView<Eigen::Upper>() +=
|
||||
// A1.transpose() * R * R * A1;
|
||||
// } else
|
||||
// throw invalid_argument("In HessianFactor::updateATA, JacobianFactor noise model is neither Unit nor Diagonal");
|
||||
// }
|
||||
// }
|
||||
// if(debug) cout << "Updating block " << slot1 << "," << slot2 << " from block " << j1 << "," << j2 << "\n";
|
||||
// if(debug) this->print();
|
||||
// }
|
||||
// }
|
||||
// toc(2, "update");
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -429,51 +445,52 @@ void HessianFactor::partialCholesky(size_t nrFrontals) {
|
|||
GaussianBayesNet::shared_ptr
|
||||
HessianFactor::splitEliminatedFactor(size_t nrFrontals, const vector<Index>& keys) {
|
||||
|
||||
static const bool debug = false;
|
||||
static const bool debug = false;
|
||||
|
||||
// Extract conditionals
|
||||
tic(1, "extract conditionals");
|
||||
GaussianBayesNet::shared_ptr conditionals(new GaussianBayesNet());
|
||||
typedef VerticalBlockView<MatrixColMajor> BlockAb;
|
||||
BlockAb Ab(matrix_, info_);
|
||||
for(size_t j=0; j<nrFrontals; ++j) {
|
||||
// Temporarily restrict the matrix view to the conditional blocks of the
|
||||
// eliminated Ab_ matrix to create the GaussianConditional from it.
|
||||
size_t varDim = Ab(0).size2();
|
||||
Ab.rowEnd() = Ab.rowStart() + varDim;
|
||||
// Extract conditionals
|
||||
tic(1, "extract conditionals");
|
||||
GaussianBayesNet::shared_ptr conditionals(new GaussianBayesNet());
|
||||
typedef VerticalBlockView<MatrixColMajor> BlockAb;
|
||||
BlockAb Ab(matrix_, info_);
|
||||
for(size_t j=0; j<nrFrontals; ++j) {
|
||||
// Temporarily restrict the matrix view to the conditional blocks of the
|
||||
// eliminated Ab_ matrix to create the GaussianConditional from it.
|
||||
size_t varDim = Ab(0).cols();
|
||||
Ab.rowEnd() = Ab.rowStart() + varDim;
|
||||
|
||||
// Zero the entries below the diagonal (this relies on the matrix being
|
||||
// column-major).
|
||||
{
|
||||
tic(1, "zero");
|
||||
BlockAb::Block remainingMatrix(Ab.range(0, Ab.nBlocks()));
|
||||
if(remainingMatrix.size1() > 1)
|
||||
for(size_t j = 0; j < remainingMatrix.size1() - 1; ++j) {
|
||||
ublas::matrix_column<BlockAb::Block> col(ublas::column(remainingMatrix, j));
|
||||
std::fill(col.begin() + j+1, col.end(), 0.0);
|
||||
}
|
||||
toc(1, "zero");
|
||||
}
|
||||
// Zero the entries below the diagonal
|
||||
{
|
||||
tic(1, "zero");
|
||||
BlockAb::Block remainingMatrix(Ab.range(0, Ab.nBlocks()));
|
||||
zeroBelowDiagonal(remainingMatrix);
|
||||
// for(size_t j = 0; j < (size_t) remainingMatrix.rows() - 1; ++j) {
|
||||
// remainingMatrix.col(j).tail(remainingMatrix.rows() - (j+1)).setZero();
|
||||
// ublas::matrix_column<BlockAb::Block> col(ublas::column(remainingMatrix, j));
|
||||
// std::fill(col.begin() + j+1, col.end(), 0.0);
|
||||
// }
|
||||
toc(1, "zero");
|
||||
}
|
||||
|
||||
tic(2, "construct cond");
|
||||
const ublas::scalar_vector<double> sigmas(varDim, 1.0);
|
||||
conditionals->push_back(boost::make_shared<ConditionalType>(keys.begin()+j, keys.end(), 1, Ab, sigmas));
|
||||
toc(2, "construct cond");
|
||||
if(debug) conditionals->back()->print("Extracted conditional: ");
|
||||
Ab.rowStart() += varDim;
|
||||
Ab.firstBlock() += 1;
|
||||
if(debug) cout << "rowStart = " << Ab.rowStart() << ", rowEnd = " << Ab.rowEnd() << endl;
|
||||
}
|
||||
toc(1, "extract conditionals");
|
||||
tic(2, "construct cond");
|
||||
// const ublas::scalar_vector<double> sigmas(varDim, 1.0);
|
||||
Vector sigmas = Vector::Ones(varDim);
|
||||
conditionals->push_back(boost::make_shared<ConditionalType>(keys.begin()+j, keys.end(), 1, Ab, sigmas));
|
||||
toc(2, "construct cond");
|
||||
if(debug) conditionals->back()->print("Extracted conditional: ");
|
||||
Ab.rowStart() += varDim;
|
||||
Ab.firstBlock() += 1;
|
||||
if(debug) cout << "rowStart = " << Ab.rowStart() << ", rowEnd = " << Ab.rowEnd() << endl;
|
||||
}
|
||||
toc(1, "extract conditionals");
|
||||
|
||||
// Take lower-right block of Ab_ to get the new factor
|
||||
tic(2, "remaining factor");
|
||||
info_.blockStart() = nrFrontals;
|
||||
// Assign the keys
|
||||
keys_.assign(keys.begin() + nrFrontals, keys.end());
|
||||
toc(2, "remaining factor");
|
||||
// Take lower-right block of Ab_ to get the new factor
|
||||
tic(2, "remaining factor");
|
||||
info_.blockStart() = nrFrontals;
|
||||
// Assign the keys
|
||||
keys_.assign(keys.begin() + nrFrontals, keys.end());
|
||||
toc(2, "remaining factor");
|
||||
|
||||
return conditionals;
|
||||
return conditionals;
|
||||
}
|
||||
|
||||
} // gtsam
|
||||
|
|
|
@ -58,6 +58,8 @@ namespace gtsam {
|
|||
typedef boost::shared_ptr<HessianFactor> shared_ptr;
|
||||
typedef BlockInfo::Block Block;
|
||||
typedef BlockInfo::constBlock constBlock;
|
||||
typedef BlockInfo::Column Column;
|
||||
typedef BlockInfo::constColumn constColumn;
|
||||
|
||||
/** Copy constructor */
|
||||
HessianFactor(const HessianFactor& gf);
|
||||
|
@ -91,8 +93,7 @@ namespace gtsam {
|
|||
HessianFactor(const FactorGraph<GaussianFactor>& factors,
|
||||
const std::vector<size_t>& dimensions, const Scatter& scatter);
|
||||
|
||||
virtual ~HessianFactor() {
|
||||
}
|
||||
virtual ~HessianFactor() {}
|
||||
|
||||
// Implementing Testable interface
|
||||
virtual void print(const std::string& s = "") const;
|
||||
|
@ -103,14 +104,25 @@ namespace gtsam {
|
|||
/** Return the dimension of the variable pointed to by the given key iterator
|
||||
* todo: Remove this in favor of keeping track of dimensions with variables?
|
||||
*/
|
||||
virtual size_t getDim(const_iterator variable) const { return info_(variable-this->begin(), 0).size1(); }
|
||||
virtual size_t getDim(const_iterator variable) const { return info_(variable-this->begin(), 0).rows(); }
|
||||
|
||||
/** Return the number of columns and rows of the Hessian matrix */
|
||||
size_t size1() const { return info_.size1(); }
|
||||
size_t rows() const { return info_.rows(); }
|
||||
|
||||
/** Return a view of a block of the information matrix */
|
||||
constBlock info(const_iterator j1, const_iterator j2) const { return info_(j1-begin(), j2-begin()); }
|
||||
|
||||
/** returns the constant term - f from the constructors */
|
||||
double constant_term() const;
|
||||
|
||||
/** returns the full linear term - g from the constructors */
|
||||
constColumn linear_term() const;
|
||||
|
||||
/** const access to the full matrix DEBUG ONLY*/
|
||||
const InfoMatrix& raw_matrix() const { return matrix_; }
|
||||
|
||||
const BlockInfo& raw_info() const { return info_; } /// DEBUG ONLY
|
||||
|
||||
/**
|
||||
* Permutes the GaussianFactor, but for efficiency requires the permutation
|
||||
* to already be inverted. This acts just as a change-of-name for each
|
||||
|
|
|
@ -34,17 +34,10 @@
|
|||
#include <boost/lambda/bind.hpp>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
|
||||
#include <boost/numeric/ublas/triangular.hpp>
|
||||
#include <boost/numeric/ublas/io.hpp>
|
||||
#include <boost/numeric/ublas/matrix_proxy.hpp>
|
||||
#include <boost/numeric/ublas/vector_proxy.hpp>
|
||||
#include <boost/numeric/ublas/blas.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
using namespace boost::lambda;
|
||||
|
||||
namespace gtsam {
|
||||
|
@ -53,15 +46,15 @@ namespace gtsam {
|
|||
inline void JacobianFactor::assertInvariants() const {
|
||||
#ifndef NDEBUG
|
||||
IndexFactor::assertInvariants(); // The base class checks for sorted keys
|
||||
assert((size() == 0 && Ab_.size1() == 0 && Ab_.nBlocks() == 0) || size()+1 == Ab_.nBlocks());
|
||||
assert(firstNonzeroBlocks_.size() == Ab_.size1());
|
||||
assert((size() == 0 && Ab_.rows() == 0 && Ab_.nBlocks() == 0) || size()+1 == Ab_.nBlocks());
|
||||
assert(firstNonzeroBlocks_.size() == Ab_.rows());
|
||||
for(size_t i=0; i<firstNonzeroBlocks_.size(); ++i)
|
||||
assert(firstNonzeroBlocks_[i] < Ab_.nBlocks());
|
||||
#endif
|
||||
|
||||
// Check for non-finite values
|
||||
for(size_t i=0; i<Ab_.size1(); ++i)
|
||||
for(size_t j=0; j<Ab_.size2(); ++j)
|
||||
for(size_t i=0; i<Ab_.rows(); ++i)
|
||||
for(size_t j=0; j<Ab_.cols(); ++j)
|
||||
if(isnan(matrix_(i,j)))
|
||||
throw invalid_argument("JacobianFactor contains NaN matrix entries.");
|
||||
}
|
||||
|
@ -88,7 +81,7 @@ namespace gtsam {
|
|||
JacobianFactor::JacobianFactor(Index i1, const Matrix& A1,
|
||||
const Vector& b, const SharedDiagonal& model) :
|
||||
GaussianFactor(i1), model_(model), firstNonzeroBlocks_(b.size(), 0), Ab_(matrix_) {
|
||||
size_t dims[] = { A1.size2(), 1};
|
||||
size_t dims[] = { A1.cols(), 1};
|
||||
Ab_.copyStructureFrom(BlockAb(matrix_, dims, dims+2, b.size()));
|
||||
Ab_(0) = A1;
|
||||
getb() = b;
|
||||
|
@ -99,7 +92,7 @@ namespace gtsam {
|
|||
JacobianFactor::JacobianFactor(Index i1, const Matrix& A1, Index i2, const Matrix& A2,
|
||||
const Vector& b, const SharedDiagonal& model) :
|
||||
GaussianFactor(i1,i2), model_(model), firstNonzeroBlocks_(b.size(), 0), Ab_(matrix_) {
|
||||
size_t dims[] = { A1.size2(), A2.size2(), 1};
|
||||
size_t dims[] = { A1.cols(), A2.cols(), 1};
|
||||
Ab_.copyStructureFrom(BlockAb(matrix_, dims, dims+3, b.size()));
|
||||
Ab_(0) = A1;
|
||||
Ab_(1) = A2;
|
||||
|
@ -111,7 +104,7 @@ namespace gtsam {
|
|||
JacobianFactor::JacobianFactor(Index i1, const Matrix& A1, Index i2, const Matrix& A2,
|
||||
Index i3, const Matrix& A3, const Vector& b, const SharedDiagonal& model) :
|
||||
GaussianFactor(i1,i2,i3), model_(model), firstNonzeroBlocks_(b.size(), 0), Ab_(matrix_) {
|
||||
size_t dims[] = { A1.size2(), A2.size2(), A3.size2(), 1};
|
||||
size_t dims[] = { A1.cols(), A2.cols(), A3.cols(), 1};
|
||||
Ab_.copyStructureFrom(BlockAb(matrix_, dims, dims+4, b.size()));
|
||||
Ab_(0) = A1;
|
||||
Ab_(1) = A2;
|
||||
|
@ -128,7 +121,7 @@ namespace gtsam {
|
|||
{
|
||||
size_t dims[terms.size()+1];
|
||||
for(size_t j=0; j<terms.size(); ++j)
|
||||
dims[j] = terms[j].second.size2();
|
||||
dims[j] = terms[j].second.cols();
|
||||
dims[terms.size()] = 1;
|
||||
Ab_.copyStructureFrom(BlockAb(matrix_, dims, dims+terms.size()+1, b.size()));
|
||||
for(size_t j=0; j<terms.size(); ++j)
|
||||
|
@ -147,7 +140,7 @@ namespace gtsam {
|
|||
size_t j=0;
|
||||
std::list<std::pair<Index, Matrix> >::const_iterator term=terms.begin();
|
||||
for(; term!=terms.end(); ++term,++j)
|
||||
dims[j] = term->second.size2();
|
||||
dims[j] = term->second.cols();
|
||||
dims[j] = 1;
|
||||
Ab_.copyStructureFrom(BlockAb(matrix_, dims, dims+terms.size()+1, b.size()));
|
||||
j = 0;
|
||||
|
@ -170,11 +163,12 @@ namespace gtsam {
|
|||
keys_ = factor.keys_;
|
||||
Ab_.assignNoalias(factor.info_);
|
||||
size_t maxrank = choleskyCareful(matrix_).first;
|
||||
matrix_ = ublas::triangular_adaptor<AbMatrix, ublas::upper>(matrix_);
|
||||
// FIXME: replace with triangular system
|
||||
// matrix_ = ublas::triangular_adaptor<AbMatrix, ublas::upper>(matrix_);
|
||||
Ab_.rowEnd() = maxrank;
|
||||
model_ = noiseModel::Unit::Create(maxrank);
|
||||
|
||||
firstNonzeroBlocks_.resize(this->size1(), 0);
|
||||
firstNonzeroBlocks_.resize(this->rows(), 0);
|
||||
|
||||
// Sort keys
|
||||
set<Index> vars;
|
||||
|
@ -203,8 +197,9 @@ namespace gtsam {
|
|||
cout << endl;
|
||||
} else {
|
||||
for(const_iterator key=begin(); key!=end(); ++key)
|
||||
gtsam::print(getA(key), (boost::format("A[%1%]=\n")%*key).str());
|
||||
gtsam::print(getb(),"b=");
|
||||
cout << boost::format("A[%1%]=\n")%*key << getA(key) << endl;
|
||||
// gtsam::print(getA(key), (boost::format("A[%1%]=\n")%*key).str());
|
||||
cout << "b=" << getb() << endl;
|
||||
model_->print("model");
|
||||
}
|
||||
}
|
||||
|
@ -220,13 +215,14 @@ namespace gtsam {
|
|||
if(keys()!=f.keys() /*|| !model_->equals(lf->model_, tol)*/)
|
||||
return false;
|
||||
|
||||
assert(Ab_.size1() == f.Ab_.size1() && Ab_.size2() == f.Ab_.size2());
|
||||
if (!(Ab_.rows() == f.Ab_.rows() && Ab_.cols() == f.Ab_.cols()))
|
||||
return false;
|
||||
|
||||
constABlock Ab1(Ab_.range(0, Ab_.nBlocks()));
|
||||
constABlock Ab2(f.Ab_.range(0, f.Ab_.nBlocks()));
|
||||
for(size_t row=0; row<Ab1.size1(); ++row)
|
||||
if(!equal_with_abs_tol(ublas::row(Ab1, row), ublas::row(Ab2, row), tol) &&
|
||||
!equal_with_abs_tol(-ublas::row(Ab1, row), ublas::row(Ab2, row), tol))
|
||||
for(size_t row=0; row< (size_t) Ab1.rows(); ++row)
|
||||
if(!equal_with_abs_tol(Ab1.row(row), Ab2.row(row), tol) &&
|
||||
!equal_with_abs_tol(-Ab1.row(row), Ab2.row(row), tol))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -246,7 +242,7 @@ namespace gtsam {
|
|||
vector<size_t> dimensions(size() + 1);
|
||||
size_t j = 0;
|
||||
BOOST_FOREACH(const SourceSlots::value_type& sourceSlot, sourceSlots) {
|
||||
dimensions[j++] = Ab_(sourceSlot.second).size2();
|
||||
dimensions[j++] = Ab_(sourceSlot.second).cols();
|
||||
}
|
||||
assert(j == size());
|
||||
dimensions.back() = 1;
|
||||
|
@ -255,14 +251,16 @@ namespace gtsam {
|
|||
vector<Index> oldKeys(size());
|
||||
keys_.swap(oldKeys);
|
||||
AbMatrix oldMatrix;
|
||||
BlockAb oldAb(oldMatrix, dimensions.begin(), dimensions.end(), Ab_.size1());
|
||||
BlockAb oldAb(oldMatrix, dimensions.begin(), dimensions.end(), Ab_.rows());
|
||||
Ab_.swap(oldAb);
|
||||
j = 0;
|
||||
BOOST_FOREACH(const SourceSlots::value_type& sourceSlot, sourceSlots) {
|
||||
keys_[j] = sourceSlot.first;
|
||||
ublas::noalias(Ab_(j++)) = oldAb(sourceSlot.second);
|
||||
Ab_(j++) = oldAb(sourceSlot.second);
|
||||
// ublas::noalias(Ab_(j++)) = oldAb(sourceSlot.second);
|
||||
}
|
||||
ublas::noalias(Ab_(j)) = oldAb(j);
|
||||
Ab_(j) = oldAb(j);
|
||||
// ublas::noalias(Ab_(j)) = oldAb(j);
|
||||
|
||||
// Since we're permuting the variables, ensure that entire rows from this
|
||||
// factor are copied when Combine is called
|
||||
|
@ -275,7 +273,7 @@ namespace gtsam {
|
|||
Vector e = -getb();
|
||||
if (empty()) return e;
|
||||
for(size_t pos=0; pos<size(); ++pos)
|
||||
e += ublas::prod(Ab_(pos), c[keys_[pos]]);
|
||||
e += Ab_(pos) * c[keys_[pos]];
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -289,18 +287,18 @@ namespace gtsam {
|
|||
double JacobianFactor::error(const VectorValues& c) const {
|
||||
if (empty()) return 0;
|
||||
Vector weighted = error_vector(c);
|
||||
return 0.5 * inner_prod(weighted,weighted);
|
||||
return 0.5 * weighted.dot(weighted);
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************************************* */
|
||||
Vector JacobianFactor::operator*(const VectorValues& x) const {
|
||||
Vector Ax = zero(Ab_.size1());
|
||||
Vector Ax = zero(Ab_.rows());
|
||||
if (empty()) return Ax;
|
||||
|
||||
// Just iterate over all A matrices and multiply in correct config part
|
||||
for(size_t pos=0; pos<size(); ++pos)
|
||||
Ax += ublas::prod(Ab_(pos), x[keys_[pos]]);
|
||||
Ax += Ab_(pos) * x[keys_[pos]];
|
||||
|
||||
return model_->whiten(Ax);
|
||||
}
|
||||
|
@ -341,14 +339,14 @@ namespace gtsam {
|
|||
Matrix whitenedA(model_->Whiten(getA(var)));
|
||||
// find first column index for this key
|
||||
size_t column_start = columnIndices[*var];
|
||||
for (size_t i = 0; i < whitenedA.size1(); i++)
|
||||
for (size_t j = 0; j < whitenedA.size2(); j++)
|
||||
for (size_t i = 0; i < (size_t) whitenedA.rows(); i++)
|
||||
for (size_t j = 0; j < (size_t) whitenedA.cols(); j++)
|
||||
entries.push_back(boost::make_tuple(i, column_start+j, whitenedA(i,j)));
|
||||
}
|
||||
|
||||
Vector whitenedb(model_->whiten(getb()));
|
||||
size_t bcolumn = columnIndices.back();
|
||||
for (size_t i = 0; i < whitenedb.size(); i++)
|
||||
for (size_t i = 0; i < (size_t) whitenedb.size(); i++)
|
||||
entries.push_back(boost::make_tuple(i, bcolumn, whitenedb(i)));
|
||||
|
||||
// return the result
|
||||
|
@ -371,7 +369,7 @@ namespace gtsam {
|
|||
/* ************************************************************************* */
|
||||
GaussianBayesNet::shared_ptr JacobianFactor::eliminate(size_t nrFrontals) {
|
||||
|
||||
assert(Ab_.rowStart() == 0 && Ab_.rowEnd() == matrix_.size1() && Ab_.firstBlock() == 0);
|
||||
assert(Ab_.rowStart() == 0 && Ab_.rowEnd() == (size_t) matrix_.rows() && Ab_.firstBlock() == 0);
|
||||
assert(size() >= nrFrontals);
|
||||
assertInvariants();
|
||||
|
||||
|
@ -380,50 +378,49 @@ namespace gtsam {
|
|||
if(debug) cout << "Eliminating " << nrFrontals << " frontal variables" << endl;
|
||||
if(debug) this->print("Eliminating JacobianFactor: ");
|
||||
|
||||
tic(1, "stairs");
|
||||
// Translate the left-most nonzero column indices into top-most zero row indices
|
||||
vector<int> firstZeroRows(Ab_.size2());
|
||||
{
|
||||
size_t lastNonzeroRow = 0;
|
||||
vector<int>::iterator firstZeroRowsIt = firstZeroRows.begin();
|
||||
for(size_t var=0; var<keys().size(); ++var) {
|
||||
while(lastNonzeroRow < this->size1() && firstNonzeroBlocks_[lastNonzeroRow] <= var)
|
||||
++ lastNonzeroRow;
|
||||
fill(firstZeroRowsIt, firstZeroRowsIt+Ab_(var).size2(), lastNonzeroRow);
|
||||
firstZeroRowsIt += Ab_(var).size2();
|
||||
}
|
||||
assert(firstZeroRowsIt+1 == firstZeroRows.end());
|
||||
*firstZeroRowsIt = this->size1();
|
||||
}
|
||||
toc(1, "stairs");
|
||||
// tic(1, "stairs");
|
||||
// // Translate the left-most nonzero column indices into top-most zero row indices
|
||||
// vector<int> firstZeroRows(Ab_.cols());
|
||||
// {
|
||||
// size_t lastNonzeroRow = 0;
|
||||
// vector<int>::iterator firstZeroRowsIt = firstZeroRows.begin();
|
||||
// for(size_t var=0; var<keys().size(); ++var) {
|
||||
// while(lastNonzeroRow < this->rows() && firstNonzeroBlocks_[lastNonzeroRow] <= var)
|
||||
// ++ lastNonzeroRow;
|
||||
// fill(firstZeroRowsIt, firstZeroRowsIt+Ab_(var).cols(), lastNonzeroRow);
|
||||
// firstZeroRowsIt += Ab_(var).cols();
|
||||
// }
|
||||
// assert(firstZeroRowsIt+1 == firstZeroRows.end());
|
||||
// *firstZeroRowsIt = this->rows();
|
||||
// }
|
||||
// toc(1, "stairs");
|
||||
|
||||
#ifndef NDEBUG
|
||||
for(size_t col=0; col<Ab_.size2(); ++col) {
|
||||
if(debug) cout << "Staircase[" << col << "] = " << firstZeroRows[col] << endl;
|
||||
if(col != 0) assert(firstZeroRows[col] >= firstZeroRows[col-1]);
|
||||
assert(firstZeroRows[col] <= (long)this->size1());
|
||||
}
|
||||
#endif
|
||||
// #ifndef NDEBUG
|
||||
// for(size_t col=0; col<Ab_.cols(); ++col) {
|
||||
// if(debug) cout << "Staircase[" << col << "] = " << firstZeroRows[col] << endl;
|
||||
// if(col != 0) assert(firstZeroRows[col] >= firstZeroRows[col-1]);
|
||||
// assert(firstZeroRows[col] <= (long)this->rows());
|
||||
// }
|
||||
// #endif
|
||||
|
||||
if(debug) gtsam::print(matrix_, "Augmented Ab: ");
|
||||
|
||||
size_t frontalDim = Ab_.range(0,nrFrontals).size2();
|
||||
size_t frontalDim = Ab_.range(0,nrFrontals).cols();
|
||||
|
||||
if(debug) cout << "frontalDim = " << frontalDim << endl;
|
||||
|
||||
// Use in-place QR or Cholesky on dense Ab appropriate to NoiseModel
|
||||
tic(2, "QR");
|
||||
SharedDiagonal noiseModel = model_->QRColumnWise(matrix_, firstZeroRows);
|
||||
SharedDiagonal noiseModel = model_->QR(matrix_);
|
||||
toc(2, "QR");
|
||||
|
||||
// Zero the lower-left triangle. todo: not all of these entries actually
|
||||
// need to be zeroed if we are careful to start copying rows after the last
|
||||
// structural zero.
|
||||
if(matrix_.size1() > 0) {
|
||||
for(size_t j=0; j<matrix_.size2(); ++j)
|
||||
if(matrix_.rows() > 0)
|
||||
for(size_t j=0; j<(size_t) matrix_.cols(); ++j)
|
||||
for(size_t i=j+1; i<noiseModel->dim(); ++i)
|
||||
matrix_(i,j) = 0.0;
|
||||
}
|
||||
|
||||
if(debug) gtsam::print(matrix_, "QR result: ");
|
||||
if(debug) noiseModel->print("QR result noise model: ");
|
||||
|
@ -441,9 +438,10 @@ namespace gtsam {
|
|||
for(size_t j=0; j<nrFrontals; ++j) {
|
||||
// Temporarily restrict the matrix view to the conditional blocks of the
|
||||
// eliminated Ab matrix to create the GaussianConditional from it.
|
||||
size_t varDim = Ab_(0).size2();
|
||||
size_t varDim = Ab_(0).cols();
|
||||
Ab_.rowEnd() = Ab_.rowStart() + varDim;
|
||||
const ublas::vector_range<const Vector> sigmas(noiseModel->sigmas(), ublas::range(Ab_.rowStart(), Ab_.rowEnd()));
|
||||
const Eigen::VectorBlock<const Vector> sigmas = noiseModel->sigmas().segment(Ab_.rowStart(), Ab_.rowEnd()-Ab_.rowStart());
|
||||
// const ublas::vector_range<const Vector> sigmas(noiseModel->sigmas(), ublas::range(Ab_.rowStart(), Ab_.rowEnd()));
|
||||
conditionals->push_back(boost::make_shared<ConditionalType>(begin()+j, end(), 1, Ab_, sigmas));
|
||||
if(debug) conditionals->back()->print("Extracted conditional: ");
|
||||
Ab_.rowStart() += varDim;
|
||||
|
@ -463,14 +461,14 @@ namespace gtsam {
|
|||
else
|
||||
model_ = noiseModel::Diagonal::Sigmas(sub(noiseModel->sigmas(), frontalDim, noiseModel->dim()));
|
||||
if(debug) this->print("Eliminated factor: ");
|
||||
assert(Ab_.size1() <= Ab_.size2()-1);
|
||||
assert(Ab_.rows() <= Ab_.cols()-1);
|
||||
toc(4, "remaining factor");
|
||||
|
||||
// todo SL: deal with "dead" pivot columns!!!
|
||||
tic(5, "rowstarts");
|
||||
size_t varpos = 0;
|
||||
firstNonzeroBlocks_.resize(this->size1());
|
||||
for(size_t row=0; row<size1(); ++row) {
|
||||
firstNonzeroBlocks_.resize(this->rows());
|
||||
for(size_t row=0; row<rows(); ++row) {
|
||||
if(debug) cout << "row " << row << " varpos " << varpos << " Ab_.offset(varpos)=" << Ab_.offset(varpos) << " Ab_.offset(varpos+1)=" << Ab_.offset(varpos+1) << endl;
|
||||
while(varpos < this->size() && Ab_.offset(varpos+1)-Ab_.offset(0) <= row)
|
||||
++ varpos;
|
||||
|
@ -490,7 +488,7 @@ namespace gtsam {
|
|||
/* ************************************************************************* */
|
||||
void JacobianFactor::collectInfo(size_t index, vector<_RowSource>& rowSources) const {
|
||||
assertInvariants();
|
||||
for (size_t row = 0; row < size1(); ++row) {
|
||||
for (size_t row = 0; row < rows(); ++row) {
|
||||
Index firstNonzeroVar;
|
||||
if (firstNonzeroBlocks_[row] < size()) {
|
||||
firstNonzeroVar = keys_[firstNonzeroBlocks_[row]];
|
||||
|
@ -518,18 +516,20 @@ namespace gtsam {
|
|||
/* ************************************************************************* */
|
||||
void JacobianFactor::copyRow(const JacobianFactor& source, Index sourceRow,
|
||||
size_t sourceSlot, size_t row, Index slot) {
|
||||
ABlock combinedBlock(Ab_(slot));
|
||||
ABlock combinedBlock = Ab_(slot);
|
||||
if (sourceSlot != numeric_limits<Index>::max()) {
|
||||
if (source.firstNonzeroBlocks_[sourceRow] <= sourceSlot) {
|
||||
const constABlock sourceBlock(source.Ab_(sourceSlot));
|
||||
ublas::noalias(ublas::row(combinedBlock, row)) = ublas::row(
|
||||
sourceBlock, sourceRow);
|
||||
} else
|
||||
ublas::noalias(ublas::row(combinedBlock, row)) = ublas::zero_vector<
|
||||
double>(combinedBlock.size2());
|
||||
} else
|
||||
ublas::noalias(ublas::row(combinedBlock, row)) = ublas::zero_vector<
|
||||
double>(combinedBlock.size2());
|
||||
combinedBlock.row(row).noalias() = sourceBlock.row(sourceRow);
|
||||
// ublas::noalias(ublas::row(combinedBlock, row)) = ublas::row(sourceBlock, sourceRow);
|
||||
} else {
|
||||
combinedBlock.row(row).setZero();
|
||||
// ublas::noalias(ublas::row(combinedBlock, row)) = ublas::zero_vector<double>(combinedBlock.cols());
|
||||
}
|
||||
} else {
|
||||
combinedBlock.row(row).setZero();
|
||||
// ublas::noalias(ublas::row(combinedBlock, row)) = ublas::zero_vector<double>(combinedBlock.cols());
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -615,7 +615,7 @@ namespace gtsam {
|
|||
Index i = 0;
|
||||
BOOST_FOREACH(const JacobianFactor::shared_ptr& factor, fg) {
|
||||
for(JacobianFactor::const_iterator j = factor->begin(); j != factor->end(); ++j) {
|
||||
r[i] += prod(factor->getA(j), x[*j]);
|
||||
r[i] += factor->getA(j) * x[*j];
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
@ -627,7 +627,7 @@ namespace gtsam {
|
|||
Index i = 0;
|
||||
BOOST_FOREACH(const JacobianFactor::shared_ptr& factor, fg) {
|
||||
for(JacobianFactor::const_iterator j = factor->begin(); j != factor->end(); ++j) {
|
||||
x[*j] += prod(trans(factor->getA(j)), r[i]);
|
||||
x[*j] += factor->getA(j).transpose() * r[i];
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
|
|
@ -42,10 +42,11 @@ namespace gtsam {
|
|||
template<class C> class BayesNet;
|
||||
|
||||
class JacobianFactor : public GaussianFactor {
|
||||
public:
|
||||
typedef MatrixColMajor AbMatrix;
|
||||
typedef VerticalBlockView<AbMatrix> BlockAb;
|
||||
|
||||
protected:
|
||||
typedef MatrixColMajor AbMatrix;
|
||||
typedef VerticalBlockView<AbMatrix> BlockAb;
|
||||
|
||||
SharedDiagonal model_; // Gaussian noise model with diagonal covariance matrix
|
||||
std::vector<size_t> firstNonzeroBlocks_;
|
||||
|
@ -70,6 +71,8 @@ namespace gtsam {
|
|||
/** Construct Null factor */
|
||||
JacobianFactor(const Vector& b_in);
|
||||
|
||||
// FIXME: make these constructors use other matrix types - column major and blocks
|
||||
|
||||
/** Construct unary factor */
|
||||
JacobianFactor(Index i1, const Matrix& A1,
|
||||
const Vector& b, const SharedDiagonal& model);
|
||||
|
@ -111,7 +114,7 @@ namespace gtsam {
|
|||
* not necessarily mean that the factor involves no variables (to check for
|
||||
* involving no variables use keys().empty()).
|
||||
*/
|
||||
bool empty() const { return Ab_.size1() == 0;}
|
||||
bool empty() const { return Ab_.rows() == 0;}
|
||||
|
||||
/** is noise model constrained ? */
|
||||
bool isConstrained() const { return model_->isConstrained();}
|
||||
|
@ -119,7 +122,7 @@ namespace gtsam {
|
|||
/** Return the dimension of the variable pointed to by the given key iterator
|
||||
* todo: Remove this in favor of keeping track of dimensions with variables?
|
||||
*/
|
||||
virtual size_t getDim(const_iterator variable) const { return Ab_(variable - begin()).size2(); }
|
||||
virtual size_t getDim(const_iterator variable) const { return Ab_(variable - begin()).cols(); }
|
||||
|
||||
/**
|
||||
* Permutes the GaussianFactor, but for efficiency requires the permutation
|
||||
|
@ -131,17 +134,17 @@ namespace gtsam {
|
|||
/**
|
||||
* return the number of columns in the corresponding linear system
|
||||
*/
|
||||
size_t size1() const { return Ab_.size1(); }
|
||||
size_t rows() const { return Ab_.rows(); }
|
||||
|
||||
/**
|
||||
* return the number of rows in the corresponding linear system
|
||||
*/
|
||||
size_t numberOfRows() const { return size1(); }
|
||||
size_t numberOfRows() const { return rows(); }
|
||||
|
||||
/**
|
||||
* return the number of columns in the corresponding linear system
|
||||
*/
|
||||
size_t size2() const { return Ab_.size2(); }
|
||||
size_t cols() const { return Ab_.cols(); }
|
||||
|
||||
/** get a copy of model */
|
||||
const SharedDiagonal& get_model() const { return model_; }
|
||||
|
@ -150,12 +153,12 @@ namespace gtsam {
|
|||
SharedDiagonal& get_model() { return model_; }
|
||||
|
||||
/** Get a view of the r.h.s. vector b */
|
||||
constBVector getb() const { return Ab_.column(size(), 0); }
|
||||
inline const constBVector getb() const { return Ab_.column(size(), 0); }
|
||||
|
||||
/** Get a view of the A matrix for the variable pointed to be the given key iterator */
|
||||
constABlock getA(const_iterator variable) const { return Ab_(variable - begin()); }
|
||||
|
||||
BVector getb() { return Ab_.column(size(), 0); }
|
||||
inline BVector getb() { return Ab_.column(size(), 0); }
|
||||
|
||||
ABlock getA(iterator variable) { return Ab_(variable - begin()); }
|
||||
|
||||
|
@ -180,6 +183,18 @@ namespace gtsam {
|
|||
*/
|
||||
Matrix matrix_augmented(bool weight = true) const;
|
||||
|
||||
/**
|
||||
* Returns full dense matrix underying factor
|
||||
* TESTING ONLY
|
||||
*/
|
||||
const AbMatrix& raw_matrix() const { return matrix_; }
|
||||
|
||||
/**
|
||||
* Returns the block indexing view
|
||||
* TESTING ONLY
|
||||
*/
|
||||
const BlockAb& Ab() const { return Ab_; }
|
||||
|
||||
/**
|
||||
* Return vector of i, j, and s to generate an m-by-n sparse matrix
|
||||
* such that S(i(k),j(k)) = s(k), which can be given to MATLAB's sparse.
|
||||
|
|
|
@ -68,10 +68,6 @@ LDADD = liblinear.la ../inference/libinference.la ../base/libbase.la
|
|||
LDADD += ../../CppUnitLite/libCppUnitLite.a
|
||||
AM_DEFAULT_SOURCE_EXT = .cpp
|
||||
|
||||
if USE_ACCELERATE_MACOS
|
||||
AM_LDFLAGS += -Wl,/System/Library/Frameworks/Accelerate.framework/Accelerate
|
||||
endif
|
||||
|
||||
# rule to run an executable
|
||||
%.run: % $(LDADD)
|
||||
./$^
|
||||
|
@ -80,7 +76,3 @@ endif
|
|||
%.valgrind: % $(LDADD)
|
||||
valgrind ./$^
|
||||
|
||||
if USE_LAPACK
|
||||
AM_CXXFLAGS += -DGT_USE_LAPACK
|
||||
endif
|
||||
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
#include <typeinfo>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <boost/numeric/ublas/lu.hpp>
|
||||
#include <boost/numeric/ublas/io.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/random/linear_congruential.hpp>
|
||||
#include <boost/random/normal_distribution.hpp>
|
||||
|
@ -33,10 +31,6 @@
|
|||
#include <gtsam/base/cholesky.h>
|
||||
#include <gtsam/linear/NoiseModel.h>
|
||||
#include <gtsam/linear/SharedDiagonal.h>
|
||||
#include <gtsam/base/DenseQRUtil.h>
|
||||
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
typedef ublas::matrix_column<Matrix> column;
|
||||
|
||||
static double inf = std::numeric_limits<double>::infinity();
|
||||
using namespace std;
|
||||
|
@ -59,23 +53,25 @@ namespace noiseModel {
|
|||
// Linear algebra: takes away projection on latest orthogonal
|
||||
// Graph: make a new factor on the separator S
|
||||
// __attribute__ ((noinline)) // uncomment to prevent inlining when profiling
|
||||
static void updateAb(Matrix& Ab, int j, const Vector& a, const Vector& rd) {
|
||||
size_t m = Ab.size1(), n = Ab.size2()-1;
|
||||
|
||||
for (size_t i = 0; i < m; i++) { // update all rows
|
||||
double ai = a(i);
|
||||
double *Aij = Ab.data().begin() + i * (n+1) + j + 1;
|
||||
const double *rptr = rd.data().begin() + j + 1;
|
||||
// Ab(i,j+1:end) -= ai*rd(j+1:end)
|
||||
for (size_t j2 = j + 1; j2 < n+1; j2++, Aij++, rptr++)
|
||||
*Aij -= ai * (*rptr);
|
||||
}
|
||||
template<class MATRIX>
|
||||
void updateAb(MATRIX& Ab, int j, const Vector& a, const Vector& rd) {
|
||||
size_t n = Ab.cols()-1;
|
||||
Ab.middleCols(j+1,n-j) -= a * rd.segment(j+1, n-j).transpose();
|
||||
// size_t m = Ab.rows(), n = Ab.cols()-1;
|
||||
// for (size_t i = 0; i < m; i++) { // update all rows
|
||||
// double ai = a(i);
|
||||
// double *Aij = Ab.data() + i * (n+1) + j + 1;
|
||||
// const double *rptr = rd.data() + j + 1;
|
||||
// // Ab(i,j+1:end) -= ai*rd(j+1:end)
|
||||
// for (size_t j2 = j + 1; j2 < n+1; j2++, Aij++, rptr++)
|
||||
// *Aij -= ai * (*rptr);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************************************* */
|
||||
Gaussian::shared_ptr Gaussian::Covariance(const Matrix& covariance, bool smart) {
|
||||
size_t m = covariance.size1(), n = covariance.size2();
|
||||
size_t m = covariance.rows(), n = covariance.cols();
|
||||
if (m != n) throw invalid_argument("Gaussian::Covariance: covariance not square");
|
||||
if (smart) {
|
||||
// check all non-diagonal entries
|
||||
|
@ -118,7 +114,7 @@ Vector Gaussian::unwhiten(const Vector& v) const {
|
|||
double Gaussian::Mahalanobis(const Vector& v) const {
|
||||
// Note: for Diagonal, which does ediv_, will be correct for constraints
|
||||
Vector w = whiten(v);
|
||||
return inner_prod(w, w);
|
||||
return w.dot(w);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -133,18 +129,18 @@ void Gaussian::WhitenInPlace(Matrix& H) const {
|
|||
|
||||
/* ************************************************************************* */
|
||||
void Gaussian::WhitenInPlace(MatrixColMajor& H) const {
|
||||
H = ublas::prod(thisR(), H);
|
||||
H = thisR() * H;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
// General QR, see also special version in Constrained
|
||||
SharedDiagonal Gaussian::QR(Matrix& Ab, boost::optional<vector<int>&> firstZeroRows) const {
|
||||
SharedDiagonal Gaussian::QR(Matrix& Ab) const {
|
||||
|
||||
static const bool debug = false;
|
||||
|
||||
// get size(A) and maxRank
|
||||
// TODO: really no rank problems ?
|
||||
size_t m = Ab.size1(), n = Ab.size2()-1;
|
||||
size_t m = Ab.rows(), n = Ab.cols()-1;
|
||||
size_t maxRank = min(m,n);
|
||||
|
||||
// pre-whiten everything (cheaply if possible)
|
||||
|
@ -152,126 +148,43 @@ SharedDiagonal Gaussian::QR(Matrix& Ab, boost::optional<vector<int>&> firstZeroR
|
|||
|
||||
if(debug) gtsam::print(Ab, "Whitened Ab: ");
|
||||
|
||||
// Perform in-place Householder
|
||||
#ifdef GT_USE_LAPACK
|
||||
if(firstZeroRows)
|
||||
householder_denseqr(Ab, &(*firstZeroRows)[0]);
|
||||
else
|
||||
householder_denseqr(Ab);
|
||||
#else
|
||||
householder(Ab, maxRank);
|
||||
#endif
|
||||
// Eigen QR - much faster than older householder approach
|
||||
inplace_QR(Ab, false);
|
||||
|
||||
// hand-coded householder implementation
|
||||
// TODO: necessary to isolate last column?
|
||||
// householder(Ab, maxRank);
|
||||
|
||||
return Unit::Create(maxRank);
|
||||
}
|
||||
|
||||
// Special version of QR for Constrained calls slower but smarter code
|
||||
// that deals with possibly zero sigmas
|
||||
// It is Gram-Schmidt orthogonalization rather than Householder
|
||||
// Previously Diagonal::QR
|
||||
/*SharedDiagonal Gaussian::QR(Matrix& Ab, boost::optional<std::vector<long>&> firstZeroRows) const {
|
||||
|
||||
WhitenInPlace(Ab);
|
||||
// get size(A) and maxRank
|
||||
size_t m = Ab.size1(), n = Ab.size2()-1;
|
||||
size_t maxRank = min(m,n);
|
||||
|
||||
// create storage for [R d]
|
||||
typedef boost::tuple<size_t, Vector, double> Triple;
|
||||
list<Triple> Rd;
|
||||
|
||||
Vector pseudo(m); // allocate storage for pseudo-inverse
|
||||
Vector weights = ones(m); // calculate weights once
|
||||
|
||||
// We loop over all columns, because the columns that can be eliminated
|
||||
// are not necessarily contiguous. For each one, estimate the corresponding
|
||||
// scalar variable x as d-rS, with S the separator (remaining columns).
|
||||
// Then update A and b by substituting x with d-rS, zero-ing out x's column.
|
||||
for (size_t j=0; j<n; ++j) {
|
||||
// extract the first column of A
|
||||
// ublas::matrix_column is slower ! TODO Really, why ????
|
||||
// AGC: if you use column() you will automatically call ublas, use
|
||||
// column_() to actually use the one in our library
|
||||
Vector a(column(Ab, j));
|
||||
|
||||
// Calculate weighted pseudo-inverse and corresponding precision
|
||||
double precision = weightedPseudoinverse(a, weights, pseudo);
|
||||
|
||||
// If precision is zero, no information on this column
|
||||
// This is actually not limited to constraints, could happen in Gaussian::QR
|
||||
// In that case, we're probably hosed. TODO: make sure Householder is rank-revealing
|
||||
if (precision < 1e-8) continue;
|
||||
|
||||
// create solution [r d], rhs is automatically r(n)
|
||||
Vector rd(n+1); // uninitialized !
|
||||
rd(j)=1.0; // put 1 on diagonal
|
||||
for (size_t j2=j+1; j2<n+1; ++j2) // and fill in remainder with dot-products
|
||||
rd(j2) = inner_prod(pseudo, ublas::matrix_column<Matrix>(Ab, j2));
|
||||
|
||||
// construct solution (r, d, sigma)
|
||||
Rd.push_back(boost::make_tuple(j, rd, precision));
|
||||
|
||||
// exit after rank exhausted
|
||||
if (Rd.size()>=maxRank) break;
|
||||
|
||||
// update Ab, expensive, using outer product
|
||||
updateAb(Ab, j, a, rd);
|
||||
}
|
||||
|
||||
// Create storage for precisions
|
||||
Vector precisions(Rd.size());
|
||||
|
||||
// Write back result in Ab, imperative as we are
|
||||
// TODO: test that is correct if a column was skipped !!!!
|
||||
size_t i = 0; // start with first row
|
||||
bool mixed = false;
|
||||
BOOST_FOREACH(const Triple& t, Rd) {
|
||||
const size_t& j = t.get<0>();
|
||||
const Vector& rd = t.get<1>();
|
||||
precisions(i) = t.get<2>();
|
||||
if (precisions(i)==inf) mixed = true;
|
||||
for (size_t j2=0; j2<j; ++j2) Ab(i,j2) = 0.0; // fill in zeros below diagonal anway
|
||||
for (size_t j2=j; j2<n+1; ++j2) // copy the j-the row TODO memcpy
|
||||
Ab(i,j2) = rd(j2);
|
||||
i+=1;
|
||||
}
|
||||
|
||||
return Unit::Create(maxRank);
|
||||
}*/
|
||||
|
||||
|
||||
/* ************************************************************************* */
|
||||
// General QR, see also special version in Constrained
|
||||
SharedDiagonal Gaussian::QRColumnWise(MatrixColMajor& Ab, vector<int>& firstZeroRows) const {
|
||||
SharedDiagonal Gaussian::QR(MatrixColMajor& Ab) const {
|
||||
|
||||
static const bool debug = false;
|
||||
|
||||
// get size(A) and maxRank
|
||||
// TODO: really no rank problems ?
|
||||
size_t m = Ab.size1(), n = Ab.size2()-1;
|
||||
size_t m = Ab.rows(), n = Ab.cols()-1;
|
||||
size_t maxRank = min(m,n);
|
||||
|
||||
// pre-whiten everything (cheaply if possible)
|
||||
WhitenInPlace(Ab);
|
||||
|
||||
if(debug) gtsam::print(Ab, "Whitened Ab: ");
|
||||
if(debug) gtsam::print(Matrix(Ab), "Whitened Ab: ");
|
||||
|
||||
// Perform in-place Householder
|
||||
#ifdef GT_USE_LAPACK
|
||||
#ifdef USE_LAPACK_QR
|
||||
householderColMajor(Ab);
|
||||
#elif USE_DAVIS_QR
|
||||
#else
|
||||
householder_denseqr_colmajor(Ab, &firstZeroRows[0]);
|
||||
#endif
|
||||
#else
|
||||
Matrix Ab_rowWise = Ab;
|
||||
householder(Ab_rowWise, maxRank);
|
||||
Ab = Ab_rowWise; // FIXME: this is a really silly way of doing this
|
||||
#endif
|
||||
// Eigen QR - much faster than older householder approach
|
||||
inplace_QR(Ab, false);
|
||||
|
||||
// hand-coded householder implementation
|
||||
// TODO: necessary to isolate last column?
|
||||
// householder(Ab, maxRank);
|
||||
|
||||
return Unit::Create(maxRank);
|
||||
}
|
||||
|
||||
|
||||
/* ************************************************************************* */
|
||||
SharedDiagonal Gaussian::Cholesky(MatrixColMajor& Ab, size_t nFrontals) const {
|
||||
// get size(A) and maxRank
|
||||
|
@ -284,7 +197,7 @@ SharedDiagonal Gaussian::Cholesky(MatrixColMajor& Ab, size_t nFrontals) const {
|
|||
|
||||
// Form A'*A (todo: this is probably less efficient than possible)
|
||||
tic("Cholesky: 2 A' * A");
|
||||
Ab = ublas::prod(ublas::trans(Ab), Ab);
|
||||
Ab = Ab.transpose() * Ab;
|
||||
toc("Cholesky: 2 A' * A");
|
||||
|
||||
// Use Cholesky to factor Ab
|
||||
|
@ -295,7 +208,7 @@ SharedDiagonal Gaussian::Cholesky(MatrixColMajor& Ab, size_t nFrontals) const {
|
|||
// Due to numerical error the rank could appear to be more than the number
|
||||
// of variables. The important part is that it does not includes the
|
||||
// augmented b column.
|
||||
if(maxrank == Ab.size2())
|
||||
if(maxrank == (size_t) Ab.cols())
|
||||
-- maxrank;
|
||||
|
||||
return Unit::Create(maxrank);
|
||||
|
@ -332,7 +245,7 @@ Diagonal::shared_ptr Diagonal::Variances(const Vector& variances, bool smart) {
|
|||
Diagonal::shared_ptr Diagonal::Sigmas(const Vector& sigmas, bool smart) {
|
||||
if (smart) {
|
||||
// look for zeros to make a constraint
|
||||
for (size_t i=0; i<sigmas.size(); ++i)
|
||||
for (size_t i=0; i< (size_t) sigmas.size(); ++i)
|
||||
if (sigmas(i)<1e-8)
|
||||
return Constrained::MixedSigmas(sigmas);
|
||||
}
|
||||
|
@ -422,16 +335,15 @@ void Constrained::WhitenInPlace(MatrixColMajor& H) const {
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
// Special version of QR for Constrained calls slower but smarter code
|
||||
// that deals with possibly zero sigmas
|
||||
// It is Gram-Schmidt orthogonalization rather than Householder
|
||||
// Previously Diagonal::QR
|
||||
SharedDiagonal Constrained::QR(Matrix& Ab, boost::optional<std::vector<int>&> firstZeroRows) const {
|
||||
// templated generic constrained QR
|
||||
template<class MATRIX>
|
||||
SharedDiagonal constrained_QR(MATRIX& Ab, const Vector& sigmas) {
|
||||
|
||||
bool verbose = false;
|
||||
if (verbose) cout << "\nStarting Constrained::QR" << endl;
|
||||
|
||||
// get size(A) and maxRank
|
||||
size_t m = Ab.size1(), n = Ab.size2()-1;
|
||||
size_t m = Ab.rows(), n = Ab.cols()-1;
|
||||
size_t maxRank = min(m,n);
|
||||
|
||||
// create storage for [R d]
|
||||
|
@ -439,7 +351,7 @@ SharedDiagonal Constrained::QR(Matrix& Ab, boost::optional<std::vector<int>&> fi
|
|||
list<Triple> Rd;
|
||||
|
||||
Vector pseudo(m); // allocate storage for pseudo-inverse
|
||||
Vector invsigmas = reciprocal(sigmas_);
|
||||
Vector invsigmas = reciprocal(sigmas);
|
||||
Vector weights = emul(invsigmas,invsigmas); // calculate weights once
|
||||
|
||||
// We loop over all columns, because the columns that can be eliminated
|
||||
|
@ -448,24 +360,25 @@ SharedDiagonal Constrained::QR(Matrix& Ab, boost::optional<std::vector<int>&> fi
|
|||
// Then update A and b by substituting x with d-rS, zero-ing out x's column.
|
||||
for (size_t j=0; j<n; ++j) {
|
||||
// extract the first column of A
|
||||
// ublas::matrix_column is slower ! TODO Really, why ????
|
||||
// AGC: if you use column() you will automatically call ublas, use
|
||||
// column_() to actually use the one in our library
|
||||
Vector a(column(Ab, j));
|
||||
Vector a = Ab.col(j);
|
||||
|
||||
// Calculate weighted pseudo-inverse and corresponding precision
|
||||
tic(1, "constrained_QR weightedPseudoinverse");
|
||||
double precision = weightedPseudoinverse(a, weights, pseudo);
|
||||
toc(1, "constrained_QR weightedPseudoinverse");
|
||||
|
||||
// If precision is zero, no information on this column
|
||||
// This is actually not limited to constraints, could happen in Gaussian::QR
|
||||
// In that case, we're probably hosed. TODO: make sure Householder is rank-revealing
|
||||
if (precision < 1e-8) continue;
|
||||
|
||||
tic(2, "constrained_QR create rd");
|
||||
// create solution [r d], rhs is automatically r(n)
|
||||
Vector rd(n+1); // uninitialized !
|
||||
rd(j)=1.0; // put 1 on diagonal
|
||||
for (size_t j2=j+1; j2<n+1; ++j2) // and fill in remainder with dot-products
|
||||
rd(j2) = inner_prod(pseudo, ublas::matrix_column<Matrix>(Ab, j2));
|
||||
rd(j2) = pseudo.dot(Ab.col(j2));
|
||||
toc(2, "constrained_QR create rd");
|
||||
|
||||
// construct solution (r, d, sigma)
|
||||
Rd.push_back(boost::make_tuple(j, rd, precision));
|
||||
|
@ -474,12 +387,16 @@ SharedDiagonal Constrained::QR(Matrix& Ab, boost::optional<std::vector<int>&> fi
|
|||
if (Rd.size()>=maxRank) break;
|
||||
|
||||
// update Ab, expensive, using outer product
|
||||
updateAb(Ab, j, a, rd);
|
||||
tic(3, "constrained_QR update Ab");
|
||||
Ab.middleCols(j+1,n-j) -= a * rd.segment(j+1, n-j).transpose();
|
||||
toc(3, "constrained_QR update Ab");
|
||||
// updateAb(Ab, j, a, rd);
|
||||
}
|
||||
|
||||
// Create storage for precisions
|
||||
Vector precisions(Rd.size());
|
||||
|
||||
tic(4, "constrained_QR write back into Ab");
|
||||
// Write back result in Ab, imperative as we are
|
||||
// TODO: test that is correct if a column was skipped !!!!
|
||||
size_t i = 0; // start with first row
|
||||
|
@ -494,16 +411,23 @@ SharedDiagonal Constrained::QR(Matrix& Ab, boost::optional<std::vector<int>&> fi
|
|||
Ab(i,j2) = rd(j2);
|
||||
i+=1;
|
||||
}
|
||||
toc(4, "constrained_QR write back into Ab");
|
||||
|
||||
return mixed ? Constrained::MixedPrecisions(precisions) : Diagonal::Precisions(precisions);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
SharedDiagonal Constrained::QRColumnWise(ublas::matrix<double, ublas::column_major>& Ab, vector<int>& firstZeroRows) const {
|
||||
Matrix AbRowWise(Ab);
|
||||
SharedDiagonal result = this->QR(AbRowWise, firstZeroRows);
|
||||
Ab = AbRowWise;
|
||||
return result;
|
||||
// Special version of QR for Constrained calls slower but smarter code
|
||||
// that deals with possibly zero sigmas
|
||||
// It is Gram-Schmidt orthogonalization rather than Householder
|
||||
// Previously Diagonal::QR
|
||||
SharedDiagonal Constrained::QR(Matrix& Ab) const {
|
||||
return constrained_QR(Ab, sigmas_);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
SharedDiagonal Constrained::QR(MatrixColMajor& Ab) const {
|
||||
return constrained_QR(Ab, sigmas_);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -521,8 +445,7 @@ void Isotropic::print(const string& name) const {
|
|||
|
||||
/* ************************************************************************* */
|
||||
double Isotropic::Mahalanobis(const Vector& v) const {
|
||||
double dot = inner_prod(v, v);
|
||||
return dot * invsigma_ * invsigma_;
|
||||
return v.dot(v) * invsigma_ * invsigma_;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <gtsam/base/Testable.h>
|
||||
#include <gtsam/base/Vector.h>
|
||||
#include <gtsam/base/Matrix.h>
|
||||
|
@ -135,7 +136,7 @@ namespace gtsam {
|
|||
* @param smart, check if can be simplified to derived class
|
||||
*/
|
||||
static shared_ptr SqrtInformation(const Matrix& R) {
|
||||
return shared_ptr(new Gaussian(R.size1(),R));
|
||||
return shared_ptr(new Gaussian(R.rows(),R));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -181,12 +182,11 @@ namespace gtsam {
|
|||
* @param Ab is the m*(n+1) augmented system matrix [A b]
|
||||
* @return in-place QR factorization [R d]. Below-diagonal is undefined !!!!!
|
||||
*/
|
||||
virtual SharedDiagonal QR(Matrix& Ab, boost::optional<std::vector<int>&> firstZeroRows = boost::none) const;
|
||||
|
||||
/**
|
||||
* Version for column-wise matrices
|
||||
*/
|
||||
virtual SharedDiagonal QRColumnWise(MatrixColMajor& Ab, std::vector<int>& firstZeroRows) const;
|
||||
virtual SharedDiagonal QR(Matrix& Ab) const;
|
||||
virtual SharedDiagonal QR(MatrixColMajor& Ab) const;
|
||||
// FIXME: these previously had firstZeroRows - what did this do?
|
||||
// virtual SharedDiagonal QRColumnWise(MatrixColMajor& Ab, std::vector<int>& firstZeroRows) const;
|
||||
// virtual SharedDiagonal QR(Matrix& Ab, boost::optional<std::vector<int>&> firstZeroRows = boost::none) const;
|
||||
|
||||
/**
|
||||
* Cholesky factorization
|
||||
|
@ -374,13 +374,8 @@ namespace gtsam {
|
|||
/**
|
||||
* Apply QR factorization to the system [A b], taking into account constraints
|
||||
*/
|
||||
virtual SharedDiagonal QR(Matrix& Ab, boost::optional<std::vector<int>&> firstZeroRows = boost::none) const;
|
||||
|
||||
/**
|
||||
* Version for column-wise matrices
|
||||
*/
|
||||
virtual SharedDiagonal QRColumnWise(boost::numeric::ublas::matrix<double, boost::numeric::ublas::column_major>& Ab,
|
||||
std::vector<int>& firstZeroRows) const;
|
||||
virtual SharedDiagonal QR(Matrix& Ab) const;
|
||||
virtual SharedDiagonal QR(MatrixColMajor& Ab) const;
|
||||
|
||||
/**
|
||||
* Check constrained is always true
|
||||
|
@ -490,7 +485,7 @@ namespace gtsam {
|
|||
}
|
||||
|
||||
virtual void print(const std::string& name) const;
|
||||
virtual double Mahalanobis(const Vector& v) const {return inner_prod(v,v); }
|
||||
virtual double Mahalanobis(const Vector& v) const {return v.dot(v); }
|
||||
virtual Vector whiten(const Vector& v) const { return v; }
|
||||
virtual Vector unwhiten(const Vector& v) const { return v; }
|
||||
virtual Matrix Whiten(const Matrix& H) const { return H; }
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
/**
|
||||
* @file VectorValues.h
|
||||
* @brief Factor Graph Valuesuration
|
||||
* @brief Factor Graph Values
|
||||
* @author Richard Roberts
|
||||
*/
|
||||
|
||||
|
@ -22,8 +22,6 @@
|
|||
#include <gtsam/base/types.h>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/numeric/ublas/vector_proxy.hpp>
|
||||
#include <boost/numeric/ublas/io.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
@ -40,11 +38,10 @@ public:
|
|||
typedef boost::shared_ptr<VectorValues> shared_ptr;
|
||||
typedef _impl_iterator<VectorValues> iterator;
|
||||
typedef _impl_iterator<const VectorValues> const_iterator;
|
||||
typedef boost::numeric::ublas::vector_range<Vector> value_reference_type;
|
||||
typedef boost::numeric::ublas::vector_range<const Vector> const_value_reference_type;
|
||||
typedef boost::numeric::ublas::vector_range<Vector> mapped_type;
|
||||
typedef boost::numeric::ublas::vector_range<const Vector> const_mapped_type;
|
||||
|
||||
typedef SubVector value_reference_type;
|
||||
typedef ConstSubVector const_value_reference_type;
|
||||
typedef SubVector mapped_type;
|
||||
typedef ConstSubVector const_mapped_type;
|
||||
|
||||
/**
|
||||
* Default constructor creates an empty VectorValues. reserve(...) must be
|
||||
|
@ -105,7 +102,7 @@ public:
|
|||
Vector& vector() { return values_; }
|
||||
|
||||
/** Reserve space for a total number of variables and dimensionality */
|
||||
void reserve(Index nVars, size_t totalDims) { values_.resize(std::max(totalDims, values_.size())); varStarts_.reserve(nVars+1); }
|
||||
void reserve(Index nVars, size_t totalDims) { values_.resize(totalDims); varStarts_.reserve(nVars+1); }
|
||||
|
||||
/**
|
||||
* Append a variable using the next variable ID, and return that ID. Space
|
||||
|
@ -119,7 +116,7 @@ public:
|
|||
}
|
||||
|
||||
/** Set all elements to zero */
|
||||
void makeZero() { boost::numeric::ublas::noalias(values_) = boost::numeric::ublas::zero_vector<double>(values_.size()); }
|
||||
void makeZero() { values_.setZero(); }
|
||||
|
||||
/** print required by Testable for unit testing */
|
||||
void print(const std::string& str = "VectorValues: ") const {
|
||||
|
@ -131,13 +128,8 @@ public:
|
|||
}
|
||||
|
||||
/** equals required by Testable for unit testing */
|
||||
bool equals(const VectorValues& expected, double tol=1e-9) const {
|
||||
if(size() != expected.size()) return false;
|
||||
// iterate over all elements
|
||||
for(Index var=0; var<size(); ++var)
|
||||
if(!equal_with_abs_tol(expected[var],operator[](var),tol))
|
||||
return false;
|
||||
return true;
|
||||
bool equals(const VectorValues& x, double tol=1e-9) const {
|
||||
return varStarts_ == x.varStarts_ && equal_with_abs_tol(values_, x.values_, tol);
|
||||
}
|
||||
|
||||
/** + operator simply adds Vectors. This checks for structural equivalence
|
||||
|
@ -147,15 +139,17 @@ public:
|
|||
assert(varStarts_ == c.varStarts_);
|
||||
VectorValues result;
|
||||
result.varStarts_ = varStarts_;
|
||||
result.values_ = boost::numeric::ublas::project(values_, boost::numeric::ublas::range(0, varStarts_.back())) +
|
||||
boost::numeric::ublas::project(c.values_, boost::numeric::ublas::range(0, c.varStarts_.back()));
|
||||
result.values_ = values_.head(varStarts_.back()) + c.values_.head(varStarts_.back());
|
||||
// result.values_ = boost::numeric::ublas::project(values_, boost::numeric::ublas::range(0, varStarts_.back())) +
|
||||
// boost::numeric::ublas::project(c.values_, boost::numeric::ublas::range(0, c.varStarts_.back()));
|
||||
return result;
|
||||
}
|
||||
|
||||
void operator+=(const VectorValues& c) {
|
||||
assert(varStarts_ == c.varStarts_);
|
||||
this->values_ = boost::numeric::ublas::project(this->values_, boost::numeric::ublas::range(0, varStarts_.back())) +
|
||||
boost::numeric::ublas::project(c.values_, boost::numeric::ublas::range(0, c.varStarts_.back()));
|
||||
this->values_ += c.values_.head(varStarts_.back());
|
||||
// this->values_ = boost::numeric::ublas::project(this->values_, boost::numeric::ublas::range(0, varStarts_.back())) +
|
||||
// boost::numeric::ublas::project(c.values_, boost::numeric::ublas::range(0, c.varStarts_.back()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -219,17 +213,21 @@ public:
|
|||
// check whether there's a zero in the vector
|
||||
friend bool anyZero(const VectorValues& x, double tol=1e-5) {
|
||||
bool flag = false ;
|
||||
BOOST_FOREACH(const double &v, x.values_) {
|
||||
if ( v < tol && v > -tol) {
|
||||
size_t i=0;
|
||||
for (const double *v = x.values_.data(); i< (size_t) x.values_.size(); ++v) {
|
||||
// BOOST_FOREACH(const double &v, x.values_) {
|
||||
// double v = x(i);
|
||||
if ( *v < tol && *v > -tol) {
|
||||
flag = true ;
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Implementations of functions
|
||||
|
||||
template<class CONTAINER>
|
||||
inline VectorValues::VectorValues(const CONTAINER& dimensions) : varStarts_(dimensions.size()+1) {
|
||||
|
@ -239,7 +237,7 @@ inline VectorValues::VectorValues(const CONTAINER& dimensions) : varStarts_(dime
|
|||
BOOST_FOREACH(size_t dim, dimensions) {
|
||||
varStarts_[++var] = (varStart += dim);
|
||||
}
|
||||
values_.resize(varStarts_.back(), false);
|
||||
values_.resize(varStarts_.back());
|
||||
}
|
||||
|
||||
inline VectorValues::VectorValues(Index nVars, size_t varDim) : varStarts_(nVars+1) {
|
||||
|
@ -247,7 +245,7 @@ inline VectorValues::VectorValues(Index nVars, size_t varDim) : varStarts_(nVars
|
|||
size_t varStart = 0;
|
||||
for(Index j=1; j<=nVars; ++j)
|
||||
varStarts_[j] = (varStart += varDim);
|
||||
values_.resize(varStarts_.back(), false);
|
||||
values_.resize(varStarts_.back());
|
||||
}
|
||||
|
||||
inline VectorValues::VectorValues(const std::vector<size_t>& dimensions, const Vector& values) :
|
||||
|
@ -258,7 +256,7 @@ inline VectorValues::VectorValues(const std::vector<size_t>& dimensions, const V
|
|||
BOOST_FOREACH(size_t dim, dimensions) {
|
||||
varStarts_[++var] = (varStart += dim);
|
||||
}
|
||||
assert(varStarts_.back() == values.size());
|
||||
assert(varStarts_.back() == (size_t) values.size());
|
||||
}
|
||||
|
||||
inline VectorValues::VectorValues(const std::vector<size_t>& dimensions, const double* values) :
|
||||
|
@ -281,14 +279,18 @@ inline VectorValues VectorValues::SameStructure(const VectorValues& otherValues)
|
|||
|
||||
inline VectorValues::mapped_type VectorValues::operator[](Index variable) {
|
||||
checkVariable(variable);
|
||||
return boost::numeric::ublas::project(values_,
|
||||
boost::numeric::ublas::range(varStarts_[variable], varStarts_[variable+1]));
|
||||
const size_t start = varStarts_[variable], n = varStarts_[variable+1] - start;
|
||||
return values_.segment(start, n);
|
||||
// return boost::numeric::ublas::project(values_,
|
||||
// boost::numeric::ublas::range(varStarts_[variable], varStarts_[variable+1]));
|
||||
}
|
||||
|
||||
inline VectorValues::const_mapped_type VectorValues::operator[](Index variable) const {
|
||||
checkVariable(variable);
|
||||
return boost::numeric::ublas::project(values_,
|
||||
boost::numeric::ublas::range(varStarts_[variable], varStarts_[variable+1]));
|
||||
const size_t start = varStarts_[variable], n = varStarts_[variable+1] - start;
|
||||
return values_.segment(start, n);
|
||||
// return boost::numeric::ublas::project(values_,
|
||||
// boost::numeric::ublas::range(varStarts_[variable], varStarts_[variable+1]));
|
||||
}
|
||||
|
||||
struct DimSpec: public std::vector<size_t> {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue